[C++-sig] Segfaults in Pure Virtual Functions in Extension Module
Michael Owens
owensmk at earthlink.net
Sun May 19 19:26:10 CEST 2002
I am having problems in a Python class called Session which holds a pointer
to an abstract C++ class (session --- little 's') which represents a generic
connection to a database. The constructor will instantiate a derived session
class (implementing a specific a database connection) call its connect()
function, and assign the pointer to the p_session member of Session. It
segfaults on connect() within Session's constructor. Now I know that
session::connect() works fine as I have tested and debugged it in a regular
C++ program.
Here are the relevent functions to create Session in the module (sdbc.cc):
static PyMethodDef sdbc_functions[] =
{
{ "session", NewSession, METH_VARARGS},
{ "join", NewJoin, METH_VARARGS},
{ NULL, NULL }
};
extern "C" void initsdbc()
{
Py_InitModule("sdbc", sdbc_functions);
}
// Create a new Session object
PyObject* NewSession(PyObject *self, PyObject *args)
{
const char* driver_name;
const char* host_name;
const char* user_name;
const char* password;
const char* database;
if(!PyArg_ParseTuple(args,"sssss:Session",
&driver_name,
&host_name,
&user_name,
&password,
&database))
{
return NULL;
}
// Constructor will be instantiate a session object using these arguments
return new Session(driver_name, host_name, user_name, password, database);
}
-------------------------------------------------------------------
Here is Session's declaration (from Session.h):
-------------------------------------------------------------------
// Session is an abstract C++ class representing a generic database session.
class session;
/** This class wraps the join C++ class.*/
class Session: public PyObject
{
public:
/** Default Constructor -- nothing special.*/
Session( const char* dn,
const char* hn,
const char* un,
const char* pw,
const char* db );
~Session();
/** Python specific interfaces */
static void dealloc(PyObject *obj);
static PyObject *getattr(PyObject *obj, char *name);
static int setattr(PyObject *obj, char *name, PyObject *value);
static struct memberlist memberlist[];
static PyMethodDef methodlist[];
const char* driver_name;
const char* host_name;
const char* user_name;
const char* password;
const char* database;
session* p_session;
};
-------------------------------------------------------------------
The constructor is as follows, Here is where the segfault occurs
p_s->connect();
-------------------------------------------------------------------
Session::Session(const char* dn,
const char* hn,
const char* un,
const char* pw,
const char* db )
{
driver_name = strdup(dn);
host_name = strdup(hn);
user_name = strdup(un);
password = strdup(pw);
database = strdup(db);
// Instantiate a derived session class --- specific to sqlite_database.
sqlite_session* p_s = new sqlite_session("db");
// SEGFAULT here:
if (p_s->connect() == false)
{
printf("Failed to connect to database: Error=%s\n", p_session->error());
}
else
{
printf("Connected to database.\n");
}
// Assign to base class pointer.
p_session = p_s;
ob_type = &Session_Type;
_Py_NewReference(this);
}
Session::~Session()
{
free((void*)driver_name);
free((void*)host_name);
free((void*)user_name);
free((void*)password);
free((void*)database);
delete p_session;
}
-------------------------------------------------------------------
Here is Session's memberlist and method list(Session.cc)
-------------------------------------------------------------------
#define OFF(x) offsetof(Session, x)
struct memberlist Session::memberlist[] =
{
{"driver_name", T_STRING, OFF(driver_name)},
{"host_name", T_STRING, OFF(host_name)},
{"user_name", T_STRING, OFF(user_name)},
{"password", T_STRING, OFF(password)},
{"database", T_STRING, OFF(database)},
{NULL}
};
PyMethodDef Session::methodlist[] =
{
{ NULL, NULL}
};
-------------------------------------------------------------------
The python code is as follows:
-------------------------------------------------------------------
#!/usr/bin/python
import sdbc
s = sdbc.session("SQLite", "localhost", "root", "", "db")
# Crash. If I don't embed session within Session, there is not problem. It all
# pivots around the presence of session with Session and calling connect(). If
I don't call connect, or call one of session's non-virtual function, there is
no segfault here.
j = sdbc.join(s)
> Please post the code you used to expose A and B to Python, and a snippet of
> Python code which causes the crash.
>
> Thanks,
> Dave
More information about the Cplusplus-sig
mailing list