[Lldb-commits] [lldb] r123428 - in /lldb/trunk: include/lldb/Core/Error.h include/lldb/Symbol/ClangASTContext.h scripts/lldb.swig source/Core/Error.cpp source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Symbol/ClangASTContext.cpp test/foundation/main.m

Greg Clayton gclayton at apple.com
Thu Jan 13 20:54:56 PST 2011


Author: gclayton
Date: Thu Jan 13 22:54:56 2011
New Revision: 123428

URL: http://llvm.org/viewvc/llvm-project?rev=123428&view=rev
Log:
Fixed an error in the type map for "char **" that was a bad memory smasher.
Anytime we had a valid python list that was trying to go from Python down into
our C++ API, it was allocating too little memory and it ended up smashing
whatever was next to the allocated memory.

Added typemap conversions for "void *, size_t" so we can get 
SBProcess::ReadMemory() working. Also added a typemap for "const void *, size_t"
so we can get SBProcess::WriteMemory() to work.

Fixed an issue in the DWARF parser where we weren't correctly calculating the
DeclContext for all types and classes. We now should be a lot more accurate.
Fixes include: enums should now be setting their parent decl context correctly.
We saw a lot of examples where enums in classes were not being properly
namespace scoped. Also, classes within classes now get properly scoped.

Fixed the objective C runtime pointer checkers to let "nil" pointers through
since these are accepted by compiled code. We also now don't call "abort()"
when a pointer doesn't validate correctly since this was wreaking havoc on
the process due to the way abort() works. We now just dereference memory
which should give us an exception from which we can easily and reliably 
recover.


Modified:
    lldb/trunk/include/lldb/Core/Error.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/Core/Error.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/test/foundation/main.m

Modified: lldb/trunk/include/lldb/Core/Error.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Error.h?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Error.h (original)
+++ lldb/trunk/include/lldb/Core/Error.h Thu Jan 13 22:54:56 2011
@@ -64,9 +64,12 @@
     /// @param[in] type
     ///     The type for \a err.
     //------------------------------------------------------------------
+    Error ();
+    
     explicit
-    Error (ValueType err = 0, lldb::ErrorType type = lldb::eErrorTypeGeneric);
+    Error (ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric);
 
+    Error (const Error &rhs);
     //------------------------------------------------------------------
     /// Assignment operator.
     ///

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Thu Jan 13 22:54:56 2011
@@ -506,7 +506,10 @@
     // Enumeration Types
     //------------------------------------------------------------------
     lldb::clang_type_t
-    CreateEnumerationType (const Declaration &decl, const char *name, lldb::clang_type_t integer_qual_type);
+    CreateEnumerationType (const char *name, 
+                           clang::DeclContext *decl_ctx, 
+                           const Declaration &decl, 
+                           lldb::clang_type_t integer_qual_type);
 
     static lldb::clang_type_t
     GetEnumerationIntegerType (lldb::clang_type_t enum_clang_type);

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Thu Jan 13 22:54:56 2011
@@ -18,11 +18,11 @@
   if (PyList_Check($input)) {
     int size = PyList_Size($input);
     int i = 0;
-    $1 = (char **) malloc((size+1) * sizeof(char));
+    $1 = (char **) malloc((size+1) * sizeof(char*));
     for (i = 0; i < size; i++) {
       PyObject *o = PyList_GetItem($input,i);
       if (PyString_Check(o))
-        $1[i] = PyString_AsString(PyList_GetItem($input,i));
+        $1[i] = PyString_AsString(o);
       else {
         PyErr_SetString(PyExc_TypeError,"list must contain strings");
         free($1);
@@ -54,6 +54,43 @@
 }
 
 
+
+// typemap for an outgoing buffer
+%typemap(in) (const void *wbuffer, size_t len) {
+   if (!PyString_Check($input)) {
+       PyErr_SetString(PyExc_ValueError, "Expecting a string");
+       return NULL;
+   }
+   $1 = (void *) PyString_AsString($input);
+   $2 = PyString_Size($input);
+}
+
+// typemap for an incoming buffer
+%typemap(in) (void *rbuffer, size_t len) {
+   if (!PyInt_Check($input)) {
+       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
+       return NULL;
+   }
+   $2 = PyInt_AsLong($input);
+   if ($2 < 0) {
+       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
+       return NULL;
+   }
+   $1 = (void *) malloc($2);
+}
+
+// Return the buffer.  Discarding any previous return result
+%typemap(argout) (void *rbuffer, size_t len) {
+   Py_XDECREF($result);   /* Blow away any previous result */
+   if (result < 0) {      /* Check for I/O error */
+       free($1);
+       PyErr_SetFromErrno(PyExc_IOError);
+       return NULL;
+   }
+   $result = PyString_FromStringAndSize($1,result);
+   free($1);
+}
+
 /* The liblldb header files to be included. */
 
 %{

Modified: lldb/trunk/source/Core/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Error.cpp?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/source/Core/Error.cpp (original)
+++ lldb/trunk/source/Core/Error.cpp Thu Jan 13 22:54:56 2011
@@ -27,6 +27,13 @@
 using namespace lldb;
 using namespace lldb_private;
 
+Error::Error ():
+    m_code (0),
+    m_type (eErrorTypeInvalid),
+    m_string ()
+{
+}
+
 //----------------------------------------------------------------------
 // Default constructor
 //----------------------------------------------------------------------
@@ -36,6 +43,14 @@
     m_string ()
 {
 }
+
+Error::Error (const Error &rhs) :
+    m_code (rhs.m_code),
+    m_type (rhs.m_type),
+    m_string (rhs.m_string)
+{
+}
+
 //----------------------------------------------------------------------
 // Assignment operator
 //----------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Jan 13 22:54:56 2011
@@ -124,40 +124,45 @@
     }
 }
 
-struct BufStruct {
-    char contents[1024];
-};
-
 ClangUtilityFunction *
 AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
 {
-    std::auto_ptr<BufStruct> buf(new BufStruct);
+    char check_function_code[1024];
     
+    int len = 0;
     if (m_has_object_getClass)
     {
-        assert(snprintf(&buf->contents[0], sizeof(buf->contents),
-                        "extern \"C\" void *gdb_object_getClass(void *);      \n"
-                        "extern \"C\" void                                  \n"
-                        "%s(void *$__lldb_arg_obj)                          \n"
-                        "{                                                  \n"
-                        "   if (!gdb_object_getClass($__lldb_arg_obj))      \n"
-                        "       abort();                                    \n"
-                        "}                                                  \n",
-                        name) < sizeof(buf->contents));
+        len = ::snprintf (check_function_code, 
+                          sizeof(check_function_code),
+                          "extern \"C\" void *gdb_object_getClass(void *);    \n"
+                          "extern \"C\" void                                  \n"
+                          "%s(void *$__lldb_arg_obj)                          \n"
+                          "{                                                  \n"
+                          "   if ($__lldb_arg_obj == (void *)0)               \n"
+                          "       return; // nil is ok                        \n" 
+                          "   if (!gdb_object_getClass($__lldb_arg_obj))      \n"
+                          "       *((volatile int *)0) = 'ocgc';              \n"
+                          "}                                                  \n",
+                          name);
     }
     else
     {
-        assert(snprintf(&buf->contents[0], sizeof(buf->contents), 
-                        "extern \"C\" void *gdb_class_getClass(void *);         \n"
-                        "extern \"C\" void                                    \n"
-                        "%s(void *$__lldb_arg_obj)                            \n"
-                        "{                                                    \n"
-                        "    void **$isa_ptr = (void **)$__lldb_arg_obj;      \n"
-                        "    if (!$isa_ptr || !gdb_class_getClass(*$isa_ptr)) \n"
-                        "        abort();                                     \n"
-                        "}                                                    \n", 
-                        name) < sizeof(buf->contents));
+        len = ::snprintf (check_function_code, 
+                          sizeof(check_function_code), 
+                          "extern \"C\" void *gdb_class_getClass(void *);       \n"
+                          "extern \"C\" void                                    \n"
+                          "%s(void *$__lldb_arg_obj)                            \n"
+                          "{                                                    \n"
+                          "   if ($__lldb_arg_obj == (void *)0)                 \n"
+                          "       return; // nil is ok                          \n" 
+                          "    void **$isa_ptr = (void **)$__lldb_arg_obj;      \n"
+                          "    if (!gdb_class_getClass(*$isa_ptr))              \n"
+                          "       *((volatile int *)0) = 'ocgc';                \n"
+                          "}                                                    \n", 
+                          name);
     }
     
-    return new ClangUtilityFunction(buf->contents, name);
+    assert (len < sizeof(check_function_code));
+
+    return new ClangUtilityFunction(check_function_code, name);
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Jan 13 22:54:56 2011
@@ -1300,7 +1300,21 @@
         DWARFCompileUnitSP cu_sp;
         const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
         if (type_die != NULL)
+        {
+            // We might be coming in in the middle of a type tree (a class
+            // withing a class, an enum within a class), so parse any needed
+            // parent DIEs before we get to this one...
+            const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
+            switch (parent_die->Tag())
+            {
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+                ResolveType(cu_sp.get(), parent_die);
+                break;
+            }
             return ResolveType (cu_sp.get(), type_die);
+        }
     }
     return NULL;
 }
@@ -2651,7 +2665,9 @@
         Type *type_ptr = m_die_to_type.lookup (die);
         if (type_ptr == NULL)
         {
-            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
+            CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
+            assert (lldb_cu);
+            SymbolContext sc(lldb_cu);
             type_sp = ParseType(sc, curr_cu, die, NULL);
         }
         else if (type_ptr != DIE_IS_BEING_PARSED)
@@ -2698,45 +2714,89 @@
 clang::DeclContext *
 SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
 {
-    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
-    if (pos != m_die_to_decl_ctx.end())
-        return pos->second;
+    if (m_clang_tu_decl == NULL)
+        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
 
+    //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset());
+    const DWARFDebugInfoEntry * const decl_die = die;
     while (die != NULL)
     {
-        switch (die->Tag())
+        // If this is the original DIE that we are searching for a declaration 
+        // for, then don't look in the cache as we don't want our own decl 
+        // context to be our decl context...
+        if (decl_die != die)
         {
-        case DW_TAG_namespace:
+            DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
+            if (pos != m_die_to_decl_ctx.end())
             {
-                const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
-                if (namespace_name)
+                //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
+                return pos->second;
+            }
+
+            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
+
+            switch (die->Tag())
+            {
+            case DW_TAG_namespace:
                 {
-                    Declaration decl;   // TODO: fill in the decl object
-                    clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
-                    if (namespace_decl)
-                        m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
-                    return namespace_decl;
+                    const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
+                    if (namespace_name)
+                    {
+                        Declaration decl;   // TODO: fill in the decl object
+                        clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
+                        if (namespace_decl)
+                        {
+                            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
+                            m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
+                        }
+                        return namespace_decl;
+                    }
                 }
-            }
-            break;
+                break;
 
-        default:
-            break;
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+                {
+                    ResolveType (curr_cu, die);
+                    pos = m_die_to_decl_ctx.find(die);
+                    assert (pos != m_die_to_decl_ctx.end());
+                    if (pos != m_die_to_decl_ctx.end())
+                    {
+                        //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
+                        return pos->second;
+                    }
+                }
+                break;
+
+            default:
+                break;
+            }
         }
+
         clang::DeclContext *decl_ctx;
-        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET));
-        if (decl_ctx)
-            return decl_ctx;
-
-        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
-        if (decl_ctx)
-            return decl_ctx;
+        dw_offset_t die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
+        if (die_offset != DW_INVALID_OFFSET)
+        {
+            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
+            decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
+            if (decl_ctx != m_clang_tu_decl)
+                return decl_ctx;
+        }
+
+        die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
+        if (die_offset != DW_INVALID_OFFSET)
+        {
+            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
+            decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
+            if (decl_ctx != m_clang_tu_decl)
+                return decl_ctx;
+        }
 
         die = die->GetParent();
     }
     // Right now we have only one translation unit per module...
-    if (m_clang_tu_decl == NULL)
-        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
+    //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
     return m_clang_tu_decl;
 }
 
@@ -3051,7 +3111,7 @@
                     }
 
 
-                    if (is_forward_declaration)
+                    if (is_forward_declaration && die->HasChildren() == false)
                     {
                         // We have a forward declaration to a type and we need
                         // to try and find a full declaration. We look in the
@@ -3183,8 +3243,9 @@
                             enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 
                                                                                                   DW_ATE_signed, 
                                                                                                   byte_size * 8);
-                            clang_type = ast.CreateEnumerationType (decl, 
-                                                                    type_name_cstr, 
+                            clang_type = ast.CreateEnumerationType (type_name_cstr, 
+                                                                    GetClangDeclContextForDIE (dwarf_cu, die->GetParent()), 
+                                                                    decl,
                                                                     enumerator_clang_type);
                         }
                         else

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Jan 13 22:54:56 2011
@@ -3487,7 +3487,13 @@
 #pragma mark Enumeration Types
 
 clang_type_t
-ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type)
+ClangASTContext::CreateEnumerationType 
+(
+    const char *name, 
+    DeclContext *decl_ctx, 
+    const Declaration &decl, 
+    clang_type_t integer_qual_type
+)
 {
     // TODO: Do something intelligent with the Declaration object passed in
     // like maybe filling in the SourceLocation with it...
@@ -3499,7 +3505,7 @@
 //    const bool IsFixed = false;
 
     EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
-                                            ast_context->getTranslationUnitDecl(),
+                                            decl_ctx,
                                             SourceLocation(),
                                             name && name[0] ? &ast_context->Idents.get(name) : NULL,
                                             SourceLocation(),

Modified: lldb/trunk/test/foundation/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=123428&r1=123427&r2=123428&view=diff
==============================================================================
--- lldb/trunk/test/foundation/main.m (original)
+++ lldb/trunk/test/foundation/main.m Thu Jan 13 22:54:56 2011
@@ -98,6 +98,7 @@
 int
 Test_NSArray ()
 {
+    NSMutableArray *nil_mutable_array = nil;
     NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil];
     NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil];
     // Expressions to test here for NSArray:
@@ -105,6 +106,7 @@
     // expression array1.count
     // expression [array2 count]
     // expression array2.count
+    // expression [nil_mutable_array count]
     id obj;
     // After each object at index call, use expression and validate object
     obj = [array1 objectAtIndex: 0];
@@ -114,7 +116,7 @@
     obj = [array2 objectAtIndex: 0];
     obj = [array2 objectAtIndex: 1];
     obj = [array2 objectAtIndex: 2];
-
+    NSUInteger count = [nil_mutable_array count];
     return 0;
 }
 





More information about the lldb-commits mailing list