jingham created this revision.
jingham added a reviewer: labath.
Herald added subscribers: lldb-commits, jdoerfert.
Herald added a project: LLDB.

The "uint32_t *versions, uint32_t num_versions" wrapper makes a list with the 
number of elements that SBModule::GetVersion said it returns, but if one of 
those elements is UINT32_MAX it aborts filling the list.  If you then iterate 
over that returned list in Python, you will get a crash.  This patch will fill 
all the elements GetVersion said it had.

This comes up if you have a library with a version 0.0.0.  That returns the (to 
me) not very sensical result of 2 elements, the first of which is UINT32_MAX.

This patch is just to handle the crash that that result causes in Python.  I 
asked on lldb-dev why GetVersion does this - maybe there is some good reason I 
don't know.  But anyway, I want to treat that as a separate issue.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D59913

Files:
  packages/Python/lldbsuite/test/macosx/version_zero/Makefile
  
packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py
  packages/Python/lldbsuite/test/macosx/version_zero/dylib.c
  packages/Python/lldbsuite/test/macosx/version_zero/main.c
  scripts/Python/python-typemaps.swig

Index: scripts/Python/python-typemaps.swig
===================================================================
--- scripts/Python/python-typemaps.swig
+++ scripts/Python/python-typemaps.swig
@@ -333,18 +333,13 @@
     PyObject* list = PyList_New(count);
     for (uint32_t j = 0; j < count; j++)
     {
-        if ($1[j] < UINT32_MAX)
+        PyObject* item = PyInt_FromLong($1[j]);
+        int ok = PyList_SetItem(list,j,item);
+        if (ok != 0)
         {
-            PyObject* item = PyInt_FromLong($1[j]);
-            int ok = PyList_SetItem(list,j,item);
-            if (ok != 0)
-            {
-                $result = Py_None;
-                break;
-            }
-        }
-        else
+            $result = Py_None;
             break;
+        }
     }
     $result = list;
 }
Index: packages/Python/lldbsuite/test/macosx/version_zero/main.c
===================================================================
--- packages/Python/lldbsuite/test/macosx/version_zero/main.c
+++ packages/Python/lldbsuite/test/macosx/version_zero/main.c
@@ -0,0 +1,7 @@
+extern int func();
+
+int
+main()
+{
+  return func();
+}
Index: packages/Python/lldbsuite/test/macosx/version_zero/dylib.c
===================================================================
--- packages/Python/lldbsuite/test/macosx/version_zero/dylib.c
+++ packages/Python/lldbsuite/test/macosx/version_zero/dylib.c
@@ -0,0 +1,4 @@
+int
+func() {
+  return 5;
+}
Index: packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py
===================================================================
--- packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py
+++ packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py
@@ -0,0 +1,49 @@
+"""
+Read in a library with a version number of 0.0.0, make sure we produce a good version.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+from lldbsuite.test import decorators
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestGetVersionForZero(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    # If your test case doesn't stress debug info, the
+    # set this to true.  That way it won't be run once for
+    # each debug info format.
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @decorators.skipUnlessDarwin
+    def test_get_version_zero(self):
+        """Read in a library with a version of 0.0.0.  Test SBModule::GetVersion"""
+        self.build()
+        self.main_source_file = lldb.SBFileSpec("dylib.c")
+        self.do_test()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def do_test(self):
+        lib_name = "libDylib.dylib"
+        target = lldbutil.run_to_breakpoint_make_target(self, exe_name=lib_name)
+        module = target.FindModule(lldb.SBFileSpec(lib_name))
+        self.assertTrue(module.IsValid(), "Didn't find the libDylib.dylib module")
+        # For now the actual version numbers are wrong for a library of 0.0.0
+        # but the previous code would crash iterating over the resultant
+        # list.  So we are testing that that doesn't happen.
+        did_iterate = False
+        for elem in module.GetVersion():
+            did_iterate = True
+        self.assertTrue(did_iterate, "Didn't get into the GetVersion loop")
+
Index: packages/Python/lldbsuite/test/macosx/version_zero/Makefile
===================================================================
--- packages/Python/lldbsuite/test/macosx/version_zero/Makefile
+++ packages/Python/lldbsuite/test/macosx/version_zero/Makefile
@@ -0,0 +1,21 @@
+LEVEL = ../../make
+
+include $(LEVEL)/Makefile.rules
+
+LIB_PREFIX := lib
+LD_FLAGS := -dynamiclib -current_version 0.0.0 -install_name @executable_path/libDylib.dylib
+
+all: libDylib.dylib
+
+a.out: main.o libDylib.dylib
+	$(CC) $(CFLAGS) -o a.out main.o -L. libDylib.dylib
+
+main.o: $(SRCDIR)/main.c
+	$(CC) $(CFLAGS) -c $(SRCDIR)/main.c
+
+libDylib.dylib: dylib.o
+	$(CC) $(CFLAGS) $(LD_FLAGS) -o libDylib.dylib dylib.o
+	
+dylib.o : dylib.c
+	$(CC) $(CFLAGS) -c $(SRCDIR)/dylib.c
+ 
\ No newline at end of file
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to