[lldb-dev] What is the correct behavior of SBModule::GetVersion with a version number of 0.0.0

Jim Ingham via lldb-dev lldb-dev at lists.llvm.org
Wed Mar 27 17:36:53 PDT 2019


If you have a library that has a version number of 0.0.0, 

uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) 

will return a result of 2 (which is the number of elements it put into num_versions) and the two elements it actually stuffed into the versions array will be {UINT32_MAX, 0}.

That seems like a weird result to me, but the code goes to some trouble to make this up.  I was wondering what the reason for this is?

This came to my attention because the swig wrapper for GetVersion treats UINT32_MAX as the sign that it should stop filling elements in the list array (even if the element that is UINT32_MAX is earlier in the returned array than the result that GetVersion returns.)  That is, we do:

    uint32_t count = result;
    if (count >= arg3)
    count = arg3;
    PyObject* list = PyList_New(count);
    for (uint32_t j = 0; j < count; j++)
    {
      if (arg2[j] < UINT32_MAX)
      {
        PyObject* item = PyInt_FromLong(arg2[j]);
        int ok = PyList_SetItem(list,j,item);
        if (ok != 0)
        {
          resultobj = Py_None;
          break;
        }
      }
      else
      break;
    }

And so if the 0th element in the list in UINT32_MAX, we make a Python list that we say we are going to fill with two elements, but don't put anything in it, and so if you try to iterate over this list Python crashes.

The wrapper behavior seems clearly wrong.  If you say you are making an array with N elements, you need to put N elements in it or iterating over it will crash.  That's easy to fix.

But then if we have a library whose actual version (e.g. as printed by the llvm objdump) is 0.0.0, we will call it {4294967295, 0} which just seems weird.  

So I was wondering whether the code in GetVersion that fills the Major version with UINT32_MAX was done for some reason, or is just an accident I should fix.

BTW, this comes about because llvm::VersionTuple doesn't have a HasMajor flag, and the only way to test the validity of the major version is to call "VersionTuple::empty" and that ONLY checks the values of the version numbers.  So something that has HasMinor = true but all the version numbers are 0 will say it is empty - which also seems a little odd to me...

Jim



More information about the lldb-dev mailing list