Bug 241751

Summary: rpm-python Segmentation Fault
Product: [Fedora] Fedora Reporter: Luke Macken <lmacken>
Component: rpmAssignee: Paul Nasrat <nobody+pnasrat>
Status: CLOSED RAWHIDE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: pfrields, pmatilai
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-06-26 07:52:02 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Additional refcounting for ts/db none

Description Luke Macken 2007-05-30 08:48:03 UTC
Description of problem:
RPM explodes when doing the following:

   >>> import rpm

   >>> for x in rpm.ts().dbMatch("name", "createrepo"): print x

   ...
   Segmentation fault


Where as this works fine:

   >>> import rpm

   >>> ts = rpm.ts()

   >>> mi = ts.dbMatch("name", "createrepo")

   >>> for x in mi: print x

   ...
   <rpm.hdr object at 0x2aaaaab25090>


Version-Release number of selected component (if applicable):
rpm-4.4.2-46.fc7

rpm-python-4.4.2-46.fc7

rpm-libs-4.4.2-46.fc7

Comment 1 Paul Nasrat 2007-05-30 09:59:42 UTC
Does it work if you run from a file rather than the interpreter?

#!/usr/bin/python

import rpm
#rpm.setVerbosity(rpm.RPMLOG_DEBUG)
for x in rpm.ts().dbMatch("name", "createrepo"): print x['name']


Comment 3 Panu Matilainen 2007-05-30 10:19:48 UTC
Yeah, it crashes when running from file as well, it just needs to find a match
(eg the package needs to be installed). It basically dies trying to verify
package signature after the transaction set was already closed, see below:

Here's a debug log from the version that works:

--- 1 --- 
--> ts 0xa076f78 ++ 1 tsCreate at rpmts.c:1603
0xb7ecdb60 ++ ts 0xa076f78 db (nil)
--> ts 0xa0771b8 ++ 1 tsCreate at rpmts.c:1603
*** rpmts_Match(0xb7ecdb60) ts 0xa0771b8
XXX headerCheck
<rpm.hdr object at 0xb7ed8260>
0xb7ecdb60 -- ts 0xa0771b8 db 0xa00d408
--> ts 0xa0771b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0xa0771b8 -- 2 tsCreate at rpmts.c:856
--> ts 0xa0771b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0xa0771b8 -- 2 tsCreate at rpmts.c:856
--> ts 0xa0771b8 -- 1 tsCreate at rpmts.c:900

And here's the crasher:
--- 2 ---
--> ts 0x9c88f78 ++ 1 tsCreate at rpmts.c:1603
0xb7ebbb60 ++ ts 0x9c88f78 db (nil)
--> ts 0x9c891b8 ++ 1 tsCreate at rpmts.c:1603
*** rpmts_Match(0xb7ebbb60) ts 0x9c891b8
0xb7ebbb60 -- ts 0x9c891b8 db 0x9c1f408
--> ts 0x9c891b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x9c891b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x9c891b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x9c891b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x9c891b8 -- 1 tsCreate at rpmts.c:900
XXX headerCheck
*** glibc detected *** python: corrupted double-linked list: 0x09c89358 ***

Smells to me like a refcounting problem, triggered by the
"for x in rpm.ts().dbMatch(...)" construct.

Comment 4 Paul Nasrat 2007-05-30 10:35:06 UTC
0x00501616 in rpmDigestUpdate (ctx=0x9364388, data=0x935dc08, len=5) at digest.c:148
148         return (*ctx->Update) (ctx->param, data, len);
(gdb) bt
#0  0x00501616 in rpmDigestUpdate (ctx=0x9364388, data=0x935dc08, len=5) at
digest.c:148
#1  0x007312b0 in verifyDSASignature (ts=0x93641e0, t=<value optimized out>,
sha1ctx=0x9364360)
    at signature.c:1433
#2  0x00732b0c in rpmVerifySignature (ts=0x93641e0, 
    result=0xbf96d378 "Header V3 DSA signature: ") at signature.c:1518
#3  0x0070abb5 in headerCheck (ts=0x93641e0, uh=0xb7c85008, uc=232108,
msg=0xbf97d430)
    at package.c:632
#4  0x006006c3 in rpmdbNextIterator (mi=0x9372a80) at rpmdb.c:2280
#5  0x00ca1739 in rpmmi_iternext (s=0xb7f3b040) at rpmmi-py.c:89
#6  0x04da673c in PyType_IsSubtype () from /usr/lib/libpython2.4.so.1.0
#7  0x04d76498 in PyDictProxy_New () from /usr/lib/libpython2.4.so.1.0
#8  0x04d67ec7 in PyObject_Call () from /usr/lib/libpython2.4.so.1.0
#9  0x04dcaad1 in PyEval_EvalFrame () from /usr/lib/libpython2.4.so.1.0
#10 0x04dce1b5 in PyEval_EvalCodeEx () from /usr/lib/libpython2.4.so.1.0
#11 0x04dce293 in PyEval_EvalCode () from /usr/lib/libpython2.4.so.1.0
#12 0x04deb078 in Py_CompileString () from /usr/lib/libpython2.4.so.1.0
#13 0x04dec593 in PyRun_SimpleStringFlags () from /usr/lib/libpython2.4.so.1.0
#14 0x04df33e0 in Py_Main () from /usr/lib/libpython2.4.so.1.0
#15 0x08048582 in main (

Comment 5 Paul Nasrat 2007-05-30 14:29:49 UTC
(gdb) info break
Num Type           Disp Enb Address    What
2   breakpoint     keep y   0x00e8c32f in rpmtsFree at rpmts.c:852
        stop only if ts->nrefs = 1

#0  rpmtsFree (ts=0x85cd498) at rpmts.c:852
#1  0x00e89418 in XrpmtsiFree (tsi=0x85df048, fn=0xe9df1c "rpmts.c", ln=771) at
rpmte.c:619
#2  0x00e8c1e3 in rpmtsClean (ts=0x85cd498) at rpmts.c:771
#3  0x00e8c26c in rpmtsEmpty (ts=0x85cd498) at rpmts.c:793
#4  0x00e8c375 in rpmtsFree (ts=0x85cd498) at rpmts.c:859
#5  0x0064ad2d in rpmts_dealloc (s=0xb7f577a0) at rpmts-py.c:1497
#6  0x04d9271f in PyDict_Clear () from /usr/lib/libpython2.4.so.1.0
#7  0x04dcab47 in PyEval_EvalFrame () from /usr/lib/libpython2.4.so.1.0
#8  0x04dce1b5 in PyEval_EvalCodeEx () from /usr/lib/libpython2.4.so.1.0
#9  0x04dce293 in PyEval_EvalCode () from /usr/lib/libpython2.4.so.1.0
#10 0x04deb078 in Py_CompileString () from /usr/lib/libpython2.4.so.1.0
#11 0x04dec593 in PyRun_SimpleStringFlags () from /usr/lib/libpython2.4.so.1.0
#12 0x04df33e0 in Py_Main () from /usr/lib/libpython2.4.so.1.0
#13 0x08048582 in main ()

Looks like rpmts_dealloc gets called when the anonymous ts falls out of scope 

Comment 6 Panu Matilainen 2007-05-31 11:48:52 UTC
Created attachment 155796 [details]
Additional refcounting for ts/db

The patch adds additional refcounting to the python level ts/db object (that's
what gets deleted too early in the anonymous construct) when match iterators
are active. 

At least now the two cases seem to behave the same, and no more segfaults:
--- 1 ---
--> ts 0x9766f78 ++ 1 tsCreate at rpmts.c:1603
0xb7eddb60 ++ ts 0x9766f78 db (nil)
--> ts 0x97671b8 ++ 1 tsCreate at rpmts.c:1603
*** rpmts_Match(0xb7eddb60) ts 0x97671b8
<rpm.hdr object at 0xb7ee8260>
0xb7eddb60 -- ts 0x97671b8 db 0x96fd408
--> ts 0x97671b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x97671b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x97671b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x97671b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x97671b8 -- 1 tsCreate at rpmts.c:900

--- 2 ---
--> ts 0x9817f78 ++ 1 tsCreate at rpmts.c:1603
0xb7f2cb60 ++ ts 0x9817f78 db (nil)
--> ts 0x98181b8 ++ 1 tsCreate at rpmts.c:1603
*** rpmts_Match(0xb7f2cb60) ts 0x98181b8
<rpm.hdr object at 0xb7f37260>
0xb7f2cb60 -- ts 0x98181b8 db 0x97ae408
--> ts 0x98181b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x98181b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x98181b8 ++ 2 rpmtsi at rpmte.c:634
--> ts 0x98181b8 -- 2 tsCreate at rpmts.c:856
--> ts 0x98181b8 -- 1 tsCreate at rpmts.c:900

Comment 7 Panu Matilainen 2007-06-26 07:52:02 UTC
Fixed in next rawhide push by rpm 4.4.2.1-rc1