|
From: Ruth Ivimey-C. <Rut...@iv...> - 2009-07-19 21:21:28
|
Folks,
I'm hoping you can help. I'm writing a Qt4 program that uses the qt
plugin interface to implement loadable "instruments" reflecting
different hardware options. I use the Qt plugin interface to list,
create and delete instruments implemented by each plugin file.
The plugin creates the instrument fine, and the main program gets back
the pointer that "new" returned (as can be seen below in the
non-valgrind text: "New DTP" is in the plugin, "Created instrument" is
in the main program. The main program then deletes the instrument
"Deleting instrument"(by calling into the plugin again) and you can see
that the address remains the same "Delete DTP". I am at a loss as to why
valgrind (and the MS heap code) has "forgotten" this address ... it now
thinks (see line 1/2 way down log) that the original block address,
displayed here as 0x52990a0, was 0x5299090!
This log is from amd64/Fedora 10/valgrind 3.4.1. I've also tried this
code on 32-bit WinXP and on 64-bit Vista, they all fail, so something
bad is happening, but what? I tried a valgrind with a MC_MALLOC_REDZONE
size of 64 bytes to see if that changed anything, but it didn't show
anything different.
After the valgrind log entry I have appended code snippets: more on request.
New DTP @ 0x52990a0
Created instrument @ 0x52990a0 plugin @ 0xb398420
Deleting instrument @ 0x52990a0 plugin @ 0xb398420
Delete DTP @ 0x52990a0
==23127==
==23127== Invalid free() / delete / delete[]
==23127== at 0x4A05E4D: operator delete(void*)
(vg_replace_malloc.c:342)
==23127== by 0xB44772E:
PluginDTP41::deleteInstrument(InstrumentInterface*) (gl_dtp41.cpp:33)
==23127== by 0x43D674: SelectDevice::updateDeviceOptions()
(selectdevice.cpp:70)
==23127== by 0x443CFC: SelectDevice::qt_metacall(QMetaObject::Call,
int, void**) (moc_selectdevice.cpp:71)
==23127== by 0x3F3D559421: QMetaObject::activate(QObject*, int, int,
void**) (in /usr/lib64/libQtCore.so.4.5.1)
==23127== by 0x3F4B14A440: QComboBox::currentIndexChanged(int) (in
/usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14CAAB: (within /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14E0D0: (within /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14E21C: QComboBox::setCurrentIndex(int) (in
/usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B15300A: QComboBox::qt_metacall(QMetaObject::Call,
int, void**) (in /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F3D559421: QMetaObject::activate(QObject*, int, int,
void**) (in /usr/lib64/libQtCore.so.4.5.1)
==23127== by 0x3F3D58FE13:
QAbstractItemModel::rowsInserted(QModelIndex const&, int, int) (in
/usr/lib64/libQtCore.so.4.5.1)
==23127== Address 0x52990a0 is 16 bytes inside a block of size 96
alloc'd
==23127== at 0x4A0700C: operator new(unsigned long)
(vg_replace_malloc.c:230)
==23127== by 0xB4473A4: PluginDTP41::createInstrument(QString,
TargetDefBase const*) const (gl_dtp41.cpp:25)
==23127== by 0x43CA8C: SelectDevice::CreateNewInstrument()
(selectdevice.cpp:43)
==23127== by 0x43D29F: SelectDevice::updateDeviceOptions()
(selectdevice.cpp:62)
==23127== by 0x443CFC: SelectDevice::qt_metacall(QMetaObject::Call,
int, void**) (moc_selectdevice.cpp:71)
==23127== by 0x3F3D559421: QMetaObject::activate(QObject*, int, int,
void**) (in /usr/lib64/libQtCore.so.4.5.1)
==23127== by 0x3F4B14A440: QComboBox::currentIndexChanged(int) (in
/usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14CAAB: (within /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14E0D0: (within /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B14E21C: QComboBox::setCurrentIndex(int) (in
/usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F4B15300A: QComboBox::qt_metacall(QMetaObject::Call,
int, void**) (in /usr/lib64/libQtGui.so.4.5.1)
==23127== by 0x3F3D559421: QMetaObject::activate(QObject*, int, int,
void**) (in /usr/lib64/libQtCore.so.4.5.1)
Code in the main program that is calling createInstrument and
deleteInstrument:
------------------------------------------------------
void SelectDevice::updateDeviceOptions(void)
{
if (instrument)
{
currentPlugin->deleteInstrument(instrument);
qDebug() << "Deleting instrument @" << instrument << " plugin @"
<< currentPlugin;
instrument = NULL;
}
m_ui->cbPort->clear();
knownPortTypes.clear();
// create an instrument so as to fetch the valid port types for it...
instrument = CreateNewInstrument();
qDebug() << "Created instrument @" << instrument << " plugin @" <<
currentPlugin;
if (instrument)
{
knownPortTypes = instrument->possiblePorts();
qDebug() << "Deleting instrument @" << instrument << " plugin @"
<< currentPlugin;
currentPlugin->deleteInstrument(instrument);
instrument = NULL;
m_ui->cbPort->addItems(knownPortTypes);
}
}
------------------------------------------------------
Code in the plugin that creates/deletes objects:
------------------------------------------------------
InstrumentInterface *PluginDTP41::createInstrument(QString plugin, const
TargetDefBase *theTarget) const
{
// no need to check "plugin" string at present.
InstrumentInterface *inst = new InstrumentDTP41(theTarget);
qDebug() << "New DTP @" << inst;
return inst;
}
void PluginDTP41::deleteInstrument(InstrumentInterface *inst)
{
qDebug() << "Delete DTP @" << inst;
delete inst;
}
------------------------------------------------------
Finally code in the plugin that is called in the middle:
------------------------------------------------------
InstrumentDTP41::InstrumentDTP41(const TargetDefBase *theTarget)
: InstrumentBase(theTarget)
{
instrumentName = "DTP-41";
srand( (unsigned)time( NULL ) );
}
InstrumentDTP41::~InstrumentDTP41(void)
{
}
QStringList InstrumentDTP41::possiblePorts() const
{
QStringList ports;
ports << "COM1" << "COM2" << "COM3" << "COM4";
return ports;
}
--
Engineer, Author and Webweaver
|