Cryptic malloc crash
-
I have a basic QAction set up as a sort of test action:
actions_.network_ping_ = new QAction(tr("Ping"), this); connect(actions_.network_ping_, &QAction::triggered, this, [this] { osc_service_->send(EosOscMessage::ping()); });Whenever I trigger this action, it works as expected, and does exactly as prescribed, but then my program crashes with an error that I don't know what to do with:
PaletteRepo(74405,0x16d1ab000) malloc: Corruption of free object 0x14402bb90: msizes 25903/0 disagree PaletteRepo(74405,0x16d1ab000) malloc: *** set a breakpoint in malloc_error_break to debugThis still happens if I rewrite that lambda in the
connectcall into a slot.If I set a breakpoint and step through, it takes me to
qobjectdefs_impl.h, specifically line 116:template <typename, typename, typename, typename> struct FunctorCall; template <size_t... II, typename... SignalArgs, typename R, typename Function> struct FunctorCall<std::index_sequence<II...>, List<SignalArgs...>, R, Function> : FunctorCallBase { static void call(Function &f, void **arg) { call_internal<R>(arg, [&] { return f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...); // < This line }); } };I'm not super familiar with
mallocso I don't know whatmalloc_error_breakis or how to set a breakpoint there as the error suggests.Does anybody have any guidance here?
This is in CLion on macOS Sequoia.
-
I have a basic QAction set up as a sort of test action:
actions_.network_ping_ = new QAction(tr("Ping"), this); connect(actions_.network_ping_, &QAction::triggered, this, [this] { osc_service_->send(EosOscMessage::ping()); });Whenever I trigger this action, it works as expected, and does exactly as prescribed, but then my program crashes with an error that I don't know what to do with:
PaletteRepo(74405,0x16d1ab000) malloc: Corruption of free object 0x14402bb90: msizes 25903/0 disagree PaletteRepo(74405,0x16d1ab000) malloc: *** set a breakpoint in malloc_error_break to debugThis still happens if I rewrite that lambda in the
connectcall into a slot.If I set a breakpoint and step through, it takes me to
qobjectdefs_impl.h, specifically line 116:template <typename, typename, typename, typename> struct FunctorCall; template <size_t... II, typename... SignalArgs, typename R, typename Function> struct FunctorCall<std::index_sequence<II...>, List<SignalArgs...>, R, Function> : FunctorCallBase { static void call(Function &f, void **arg) { call_internal<R>(arg, [&] { return f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...); // < This line }); } };I'm not super familiar with
mallocso I don't know whatmalloc_error_breakis or how to set a breakpoint there as the error suggests.Does anybody have any guidance here?
This is in CLion on macOS Sequoia.
-
I have a basic QAction set up as a sort of test action:
actions_.network_ping_ = new QAction(tr("Ping"), this); connect(actions_.network_ping_, &QAction::triggered, this, [this] { osc_service_->send(EosOscMessage::ping()); });Whenever I trigger this action, it works as expected, and does exactly as prescribed, but then my program crashes with an error that I don't know what to do with:
PaletteRepo(74405,0x16d1ab000) malloc: Corruption of free object 0x14402bb90: msizes 25903/0 disagree PaletteRepo(74405,0x16d1ab000) malloc: *** set a breakpoint in malloc_error_break to debugThis still happens if I rewrite that lambda in the
connectcall into a slot.If I set a breakpoint and step through, it takes me to
qobjectdefs_impl.h, specifically line 116:template <typename, typename, typename, typename> struct FunctorCall; template <size_t... II, typename... SignalArgs, typename R, typename Function> struct FunctorCall<std::index_sequence<II...>, List<SignalArgs...>, R, Function> : FunctorCallBase { static void call(Function &f, void **arg) { call_internal<R>(arg, [&] { return f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...); // < This line }); } };I'm not super familiar with
mallocso I don't know whatmalloc_error_breakis or how to set a breakpoint there as the error suggests.Does anybody have any guidance here?
This is in CLion on macOS Sequoia.
-
I think I've figured out my issue, but maybe you knowledgeable folks can confirm:
That lambda/slot was calling some static functions from another class:
void MainWindow::s_oscSendPing() const { osc_service_->sendMessage(EosOscMessage::ping()); }--
class EosOscMessage { public: static osc::OutboundPacketStream ping() { return msgStart() << osc::BeginMessage("/eos/ping") << osc::EndMessage; } private: static osc::OutboundPacketStream msgStart() { QByteArray buffer; buffer.reserve(OscService::k_max_len); return {buffer.data(), OscService::k_max_len}; }};
Those stream operators and
oscnamespace are from an external library that operate on objects take achar*as data and anintas size.I think my issue was that I was calling
reserveon the QByteArray inmsgStartand notresize. When I change it toresizethis problem stops happening. -
I think I've figured out my issue, but maybe you knowledgeable folks can confirm:
That lambda/slot was calling some static functions from another class:
void MainWindow::s_oscSendPing() const { osc_service_->sendMessage(EosOscMessage::ping()); }--
class EosOscMessage { public: static osc::OutboundPacketStream ping() { return msgStart() << osc::BeginMessage("/eos/ping") << osc::EndMessage; } private: static osc::OutboundPacketStream msgStart() { QByteArray buffer; buffer.reserve(OscService::k_max_len); return {buffer.data(), OscService::k_max_len}; }};
Those stream operators and
oscnamespace are from an external library that operate on objects take achar*as data and anintas size.I think my issue was that I was calling
reserveon the QByteArray inmsgStartand notresize. When I change it toresizethis problem stops happening.@Jackmill
reservevsresizeisn't the root cause here; thoughresizeis the correct method to use.The problem is that by the time
msgStartreturns,buffer(which is local) is destroyed and the pointer taken frombuffer.data()is dangling. Assumingosc::OutboundPacketStreamholds on to that pointer (otherwise the method is pretty pointless), it will still crash sooner or later.In this case you need to make sure that the buffer lives long enough. Check the library documentation, to see if the
OutboundPacketStreamcan be used in a mode which owns its' buffer. -
@Jackmill
reservevsresizeisn't the root cause here; thoughresizeis the correct method to use.The problem is that by the time
msgStartreturns,buffer(which is local) is destroyed and the pointer taken frombuffer.data()is dangling. Assumingosc::OutboundPacketStreamholds on to that pointer (otherwise the method is pretty pointless), it will still crash sooner or later.In this case you need to make sure that the buffer lives long enough. Check the library documentation, to see if the
OutboundPacketStreamcan be used in a mode which owns its' buffer.@IgKh said in Cryptic malloc crash:
@Jackmill
reservevsresizeisn't the root cause here; thoughresizeis the correct method to use.The problem is that by the time
msgStartreturns,buffer(which is local) is destroyed and the pointer taken from buffer.data() is dangling.Correction: msgStart() returns the pointer returned by QByteArray::data(). If it returned
buffer, the lifetime of the object would have been extended to the end of EosOscMessage::osc::OutboundPacketStream().#include <QByteArray> #include <QString> #include <QDebug> struct Array : public QByteArray { QString m_tag; Array(QString tag) : m_tag(tag) { qDebug() << Q_FUNC_INFO << tag; } ~Array() { qDebug() << Q_FUNC_INFO << m_tag; } }; Array returnArray() { Array a("returnArray"); return a; } char * returnData() { Array a("returnData"); return a.data(); } int main(int argc, char *argv[]) { qDebug() << "returnArray()"; auto array = returnArray(); qDebug() << "/returnArray()"; qDebug() << "returnData()"; auto data = returnData(); qDebug() << "returnData()"; }Output:
returnArray() Array::Array(QString) "returnArray" /returnArray() returnData() Array::Array(QString) "returnData" Array::~Array() "returnData" returnData() Array::~Array() "returnArray" -
J Jackmill has marked this topic as solved on