[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#304296: Segfault in CppOwnedDealloc<PkgSrcRecordsStruct>



Package: python-apt
Version: 0.6.10
Severity: normal
Tags: patch

I've hit a segfault python-apt while trying to write a class that
nicely encapsulates a package.

gdb says:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1075396736 (LWP 8931)]
0x403f20bc in CppOwnedDealloc<PkgSrcRecordsStruct> () from
/usr/lib/python2.3/site-packages/apt_pkg.so

Looking at the source (at python/pkgsrcrecords.cc) there's a
mismatch in the used variants of the object allocation/deallocation
functions. Allocation is done with CppPyObject_NEW, while
deallocation is done with CppOwnedDealloc. Using the non-owned
variants everywhere the segfault is gone. 

I've attatched the python program that triggered the segfault here,
and my proposed fix.

Cheers,
Greek0

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.8r20050410
Locale: LANG=de_AT.UTF-8@euro, LC_CTYPE=de_AT.UTF-8@euro (charmap=UTF-8)

Versions of packages python-apt depends on:
ii  apt [libapt-pkg-libc6.3-5-3 0.5.28.6     Advanced front-end for dpkg
ii  apt-utils [libapt-inst-libc 0.5.28.6     APT utility programs
ii  libc6                       2.3.2.ds1-20 GNU C Library: Shared libraries an
ii  libgcc1                     1:3.4.3-12   GCC support library
ii  libstdc++5                  1:3.3.5-12   The GNU Standard C++ Library v3
ii  python                      2.3.5-2      An interactive high-level object-o

-- no debconf information
#!/usr/bin/env python2.4

import sys
import os
import re
import copy
import apt_pkg
import options

class Regexps:
	# apt-cache policy RE
	# Installed = groups(1)
	# Candidate = groups(2)
	policy = re.compile(r'^\s+Installed: (.*)$\n^\s+Candidate: (.*)$', re.M)

class Package(object):
	"""Maintains data about packages.

	This class encapsulates a package. It allows inspection of the current
	state, listing of available versions, ...

	>>> y = Package("kde")
	>>> y.is_installed()
	False
	>>> y.installed
	''
	>>> y.candidate
	'5:44'
	>>> y.source
	'xfree86'

	"""
	def __init__(self, pkgname):
		self._name = pkgname
		self._installed = None
		self._candidate = None
		self._source = None

	def _read_policy(self):
		args = ""
		if options.opts.Release != None:
			args += " -oAPT::Default-Release='%s' " % options.opts.Release

		cmdline = "apt-cache policy %s %s" % (args, self._name)

		f = os.popen(cmdline)
		policy_txt = f.read()
		f.close()

		match = Regexps.policy.search(policy_txt)
		if match.group(1) == "(none)":
			self._installed = ""
		else:
			self._installed = match.group(1)
		self._candidate = match.group(2)

	def _get_candidate(self):
		if self._candidate == None:
			self._read_policy()
		return self._candidate

	def _get_installed(self):
		if self._installed == None:
			self._read_policy()
		return self._installed

	def is_installed(self):
		if self._installed == None:
			self._read_policy()

		return bool(self._installed)

	def _get_source(self):
		if self._source == None:
			src = apt_pkg.GetPkgSrcRecords(apt_pkg.GetCache())
			src.Lookup(self._name)
			self._source = copy.deepcopy(src.Package)
			print self._source

		#return self._source


	candidate = property(_get_candidate)
	installed = property(_get_installed)
	source = property(_get_source)


def main():
	os.environ["LC_ALL"]="C"
	os.environ["LC_MESSAGES"]="C"
	options.ParseOptions()
	apt_pkg.init()
	p = Package("xterm")
	print "Installed: %s" % p.installed
	print "Candidate: %s" % p.candidate
	x = p.source
	print "x:"
	print x
	print "source:"
	print p._source

if __name__ == "__main__":
	main()
diff -ur orig.python-apt-0.6.10/python/pkgsrcrecords.cc python-apt-0.6.10/python/pkgsrcrecords.cc
--- orig.python-apt-0.6.10/python/pkgsrcrecords.cc	2003-12-26 18:04:22.000000000 +0100
+++ python-apt-0.6.10/python/pkgsrcrecords.cc	2005-04-12 08:48:46.640532096 +0200
@@ -89,10 +89,10 @@
    PyObject_HEAD_INIT(&PyType_Type)
    0,			                // ob_size
    "pkgSrcRecords",                          // tp_name
-   sizeof(CppOwnedPyObject<PkgSrcRecordsStruct>),   // tp_basicsize
+   sizeof(CppPyObject<PkgSrcRecordsStruct>),   // tp_basicsize
    0,                                   // tp_itemsize
    // Methods
-   CppOwnedDealloc<PkgSrcRecordsStruct>,   // tp_dealloc
+   CppDealloc<PkgSrcRecordsStruct>,   // tp_dealloc
    0,                                   // tp_print
    PkgSrcRecordsAttr,                      // tp_getattr
    0,                                   // tp_setattr

Attachment: signature.asc
Description: Digital signature


Reply to: