473,398 Members | 2,380 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Cyclic garbage collection and segfaults...


Hi group.

I have a problem with some C extensions I am working with and
hope that some of you can help. Basically, I am wrapping a a tree
structure from C where I have python methods for extracting either the
entire tree or subtrees; since I don't want the full tree to be
deallocated while python has references to the subtrees, I INCREF the
full tree whenever I hand out a subtree reference. I don't want any of
the subtrees to be deallocated while the full tree lives, either, so I
want the fulltree to have a reference to each of the subtrees. Naturally,
this gives me a cyclik reference structure, and I want to be able to
garbage collect it. But this is where my problems begin...

For some reason, when I turn on the cyclic garbage collection for my
types, a deallocation automatically gives me a segfault. That is, if my
type new type contains any data whatsoever, I cannot garbage collect
without dumping core. I have boiled the problem down to the code shown
below. It contains no cyclic structure, it is as simple as it gets, but
it still seqfaults for me. If I comment out the magic void-pointer (which
isn't used for anything) I don't get the segfault.
#include <Python.h>

struct SimpleObject;

static PyObject * Simple_new (PyTypeObject *type,
PyObject *args,
PyObject *kwds);
static int Simple_init (struct SimpleObject *self,
PyObject *args,
PyObject *kwds);
static int Simple_traverse(struct SimpleObject *self,
visitproc visit,
void *arg);
static void Simple_dealloc (struct SimpleObject *self);


typedef struct SimpleObject {
/* object stuff */
PyObject_HEAD

/* dark magic */
void *magic;

} SimpleObject;
static PyTypeObject simple_SimpleType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"simple.Simple", /*tp_name*/
sizeof(SimpleObject), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Simple_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
"Simple objects", /*tp_doc*/
(traverseproc)Simple_traverse, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
0, /*tp_methods*/
0, /*tp_members*/
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
(initproc)Simple_init, /*tp_init*/
0, /*tp_alloc*/
Simple_new, /*tp_new*/

0 /*...the rest...*/
};
static PyObject *
Simple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
SimpleObject *self = (SimpleObject *)type->tp_alloc(type, 0);
return (PyObject*)self;
}

static int
Simple_init(SimpleObject *self, PyObject *args, PyObject *kwds)
{
return 0;
}

/* cyclic gc */
static int
Simple_traverse (SimpleObject *self, visitproc visit, void *arg)
{
fprintf(stderr,"Simple_traverse...\n");
return 0;
}

static int
Simple_clear(SimpleObject *self)
{
fprintf(stderr,"Simple_clear...\n");
return 0;
}

static void
Simple_dealloc(SimpleObject *self)
{
fprintf(stderr,"Simple_dealloc %p\n", self);
self->ob_type->tp_free((PyObject*)self); /* <= segfault here */
return;
}

static PyMethodDef simple_methods[] = {
{0} /* sentinel */
};

void
initsimple(void)
{
if (PyType_Ready(&simple_SimpleType) < 0) return;
Py_INCREF(&simple_SimpleType);

PyObject* m = Py_InitModule3("simple", simple_methods, "Simple module.");
PyModule_AddObject(m,"Simple",(PyObject*)&simple_S impleType);
}
A script sufficient to provoke the fault is this:

import simple
simple.Simple()
Can anyone explain what I'm doing wrong? Or perhaps suggest a better
solution to my "real" problem, if I'm approaching the problem completely
wrong :-)

Yours,
/mailund

Jul 18 '05 #1
3 1766
Can anyone explain what I'm doing wrong? Or perhaps suggest a better
solution to my "real" problem, if I'm approaching the problem completely
wrong :-)

Yours,
/mailund


In my extensions python seems to segfault in the GC most of all...
Just yesterday I removed a malloc that was (why??) causing a segfault.

Have you seen pyrex ? It's absolutely brilliant. Take 2 hours to try it
out if you have the time.

Simon.

Jul 18 '05 #2
"Thomas Mailund" <ma*****@birc.dk> writes:
Hi group.

I have a problem with some C extensions I am working with and
hope that some of you can help.
[snippety]
static void
Simple_dealloc(SimpleObject *self)
{
fprintf(stderr,"Simple_dealloc %p\n", self);
self->ob_type->tp_free((PyObject*)self); /* <= segfault here */
Well, you're calling tp_free from a tp_dealloc. That doesn't *sound*
sensible to me.
Can anyone explain what I'm doing wrong? Or perhaps suggest a better
solution to my "real" problem, if I'm approaching the problem completely
wrong :-)


There are docs on this sort of thing.

Cheers,
mwh

--
"Sturgeon's Law (90% of everything is crap) applies to Usenet."
"Nothing guarantees that the 10% isn't crap, too."
-- Gene Spafford's Axiom #2 of Usenet, and a corollary
Jul 18 '05 #3
On Thu, 15 Jan 2004 11:15:51 +0000, Michael Hudson wrote:
"Thomas Mailund" <ma*****@birc.dk> writes:
Hi group.

I have a problem with some C extensions I am working with and
hope that some of you can help.


[snippety]
static void
Simple_dealloc(SimpleObject *self)
{
fprintf(stderr,"Simple_dealloc %p\n", self);
self->ob_type->tp_free((PyObject*)self); /* <= segfault here */


Well, you're calling tp_free from a tp_dealloc. That doesn't *sound*
sensible to me.


I'm suprised to hear that; the documentation I was working from,
<URL:http://www.python.org/doc/current/ext/node22.html>, does exactly
that. Of course, this is from the section that uses reference counting,
not cyclic gc, but later on, when the garbage collector is introduced, the
deallocator still calls tp_free, it just calls clear first
<URL:http://www.python.org/doc/current/ext/node24.html>.

If I shouldn't free self in this way, how should I do it?
Can anyone explain what I'm doing wrong? Or perhaps suggest a better
solution to my "real" problem, if I'm approaching the problem completely
wrong :-)


There are docs on this sort of thing.


About the garbage collection? In that case, I thought I *was* following
the documentation ;-)

If about the general problem with accessing the whole and parts of a C
structure from python, if you have any specific references in mind, I
would be very grateful if you would post them. I know that I am not the
first to have this problem, and that very likely there are general
patterns for solving the problem, but my googling didn't find anything
(which probably means I wasn't asking the right questions, but never the
less...)

Yours,
/mailund

Jul 18 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Ganesh | last post by:
Is there a utility by microsoft (or anyone) to force garbage collection in a process without have access to the process code. regards Ganesh
11
by: Rick | last post by:
Hi, My question is.. if Lisp, a 40 year old language supports garbage collection, why didn't the authors of C++ choose garbage collection for this language? Are there fundamental reasons behind...
5
by: Bob lazarchik | last post by:
Hello: We are considering developing a time critical system in C#. Our tool used in Semiconductor production and we need to be able to take meaurements at precise 10.0 ms intervals( 1000...
8
by: mike2036 | last post by:
For some reason it appears that garbage collection is releasing an object that I'm still using. The object is declared in a module and instantiated within a class that is in turn instantiated by...
28
by: Goalie_Ca | last post by:
I have been reading (or at least googling) about the potential addition of optional garbage collection to C++0x. There are numerous myths and whatnot with very little detailed information. Will...
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
2
by: skip | last post by:
We encountered a situation today where it appeared that a Boost.Python-provided class didn't participate in Python's cyclic garbage collection. The wrapped C++ instance held a reference to a...
56
by: Johnny E. Jensen | last post by:
Hellow I'am not sure what to think about the Garbage Collector. I have a Class OutlookObject, It have two private variables. Private Microsoft.Office.Interop.Outlook.Application _Application =...
158
by: pushpakulkar | last post by:
Hi all, Is garbage collection possible in C++. It doesn't come as part of language support. Is there any specific reason for the same due to the way the language is designed. Or it is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.