RPM Community Forums

Mailing List Message of <rpm-users>

Re: free() pointer error when using bindings to read specfile

From: Jeff Johnson <n3npq@mac.com>
Date: Sun 13 Sep 2009 - 18:08:51 CEST
Message-id: <3BF74DE1-4896-4AE6-A33B-DDC227A3D125@mac.com>

On Sep 13, 2009, at 11:08 AM, Eric MSP Veith wrote:

> Hello,
> I'm trying to read a spec file using RPM's bindings. I've tried both  
> rpm5-perl
> and rpm5-python and both fail with the following error:
> *** glibc detected *** python: free(): invalid next size (fast):  
> 0x08ab9040
> ***

This error is going to be RPM version specific. All memory is no
refcounted with mutexes, and malloc overhead is avoided by resusing
items from memory pools. Which is why I'm not able top reproduce on  
cvs HEAD.

> This is what the Python script gives me, the error with Perl reads  
> the same.
> My code looks as follows:
> ---->----
> #!/usr/bin/env python
> import rpm
> import os
> import sys
> if len(sys.argv) != 2:
>    print "Usage: %s SPECFILE" %(sys.argv[0])
>    exit(1)
> ts_h = rpm.TransactionSet()
> spec_h = ts_h.parseSpec(sys.argv[1])
> print spec_h.check()
> ----<----

Meanwhile, this script exercises all the available python methods
#!/usr/bin/env python

import rpm
import os
import sys

if len(sys.argv) != 2:
    print "Usage: %s SPECFILE" %(sys.argv[0])

ts_h = rpm.TransactionSet()
spec = ts_h.parseSpec(sys.argv[1])

print "----- sources:", spec.sources()
print "----- prep:", spec.prep()
print "----- build:", spec.build()
print "----- install:", spec.install()
print "----- clean:", spec.clean()
print "----- buildRoot:", spec.buildRoot()

print "----- check:", spec.check()

When run the above script a "t.py" I see:

     $ python t.py /usr/src/rpm/SPECS/popt.spec
     ----- clean: /bin/rm -rf '/var/tmp/popt-root'

     ----- buildRoot: /var/tmp/popt-root
     ----- check:
     Traceback (most recent call last):
       File "t.py", line 21, in <module>
         print "----- check:", spec.check()
     SystemError: error return without exception set

The error is because I ran the script on a popt.spec file
that does not have a %check section. Adding a try to catch
the exception would "work". Arguably this should be in
spec-py.c, but the Spec methods are primitive and there's
a vanishingly small usage case so its hardly worth the effort imho.
But a copuple lines of patching in python/spec-py.c could
do whatever is desired. Private exception for better message?
a PyNONE return? What ... ?

static PyObject *
spec_get_check(specObject * s)
     Spec spec = specFromSpec(s);
     return (spec != NULL && spec->check != NULL)
         ? Py_BuildValue("s", rpmiobStr(spec->check)) : NULL;

> The perl version looks similar, but I'm using "RPM::Spec->new 
> ($file)" instead.

The perl version has unit tests that are passing afaik. I can look  
if you have a specific failure reproducer.

I still suggest using YAML (or XML if that's your poison). Loading  
dirt simple and you end up with native objects (rather than custom  
getter/setter methods) ready for use.


73 de Jeff
Received on Sun Sep 13 18:09:12 2009
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.