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
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']
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.
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 (
(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
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
Fixed in next rawhide push by rpm 4.4.2.1-rc1