#13598: mythbackend segfault when frontend and mythweb access program listing
------------------------------------+--------------------------
Reporter: Peter Bennett | Owner: (none)
Type: Bug Report - Crash | Status: new
Priority: minor | Milestone: needs_triage
Component: MythTV - General | Version: Master Head
Severity: medium | Keywords:
Ticket locked: 0 |
------------------------------------+--------------------------
This happened twice on my development master backend, when looking at
program listings from the frontend and mythweb.
This is the log at the time
{{{
2020-02-15 14:39:26.894643 I MainServer: adding: andromeda(55971de35910)
as a file transfer
2020-02-15 14:39:26.897840 I MainServer: adding: andromeda(55971de34680)
as a file transfer
2020-02-15 14:39:26.897845 I FileTransfer sock(55971de37a70) disconnected
Handling Segmentation fault
Segmentation fault (core dumped)
}}}
Here is the relevant part of the backtrace. The segfault is in thread 1 in
code that is called from QT event processors.
{{{
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055971c7a3bab in MainServer::connectionClosed
(this=0x55971dd2ee00, socket=0x55971de37a70) at mainserver.cpp:7896
7896 (*ft)->DecrRef();
[Current thread is 1 (Thread 0x7ff91cbe9700 (LWP 10763))]
Thread 1 (Thread 0x7ff91cbe9700 (LWP 10763)):
#0 0x000055971c7a3bab in MainServer::connectionClosed(MythSocket*)
(this=0x55971dd2ee00, socket=0x55971de37a70) at mainserver.cpp:7896
sock = 0x55971de37a70
ft = 0x0
__FUNCTION__ = "connectionClosed"
cs = {i = {i = 0x7ff9698c2d20
<QSocketNotifier::setEnabled(bool)+144>}}
#1 0x00007ff96c085fe8 in MythSocket::DisconnectHandler()
(this=0x55971de37a70) at mythsocket.cpp:265
__FUNCTION__ = "DisconnectHandler"
#2 0x00007ff96c1cf885 in MythSocket::qt_static_metacall(QObject*,
QMetaObject::Call, int, void**) (_o=0x55971de37a70,
_c=QMetaObject::InvokeMetaMethod, _id=4, _a=0x7ff91cbe88c0) at
moc/moc_mythsocket.cpp:148
_t = 0x55971de37a70
}}}
This is the code around the segfault location [(*ft)->!DecrRef() is the
line which got the seg fault]
{{{
for (auto ft = m_fileTransferList.begin(); ft != m_fileTransferList.end();
++ft)
{
MythSocket *sock = (*ft)->getSocket();
if (sock == socket)
{
LOG(VB_GENERAL, LOG_INFO, QString("FileTransfer sock(%1)
disconnected")
.arg(quintptr(socket),0,16) );
(*ft)->DecrRef();
m_fileTransferList.erase(ft);
m_sockListLock.unlock();
UpdateSystemdStatus();
return;
}
}
}}}
In one backtrace ft was 0 and in the other it has a good looking value,
but examining the !FileTransfer structure it points to gives garbage, for
example the !FileTransfer m_sock object accesses an invalid location and
some boolean variables have values like 114 instead of true or false.
My dilemma is: How can ft (a variable on the stack) be corrupted between
the call to (*ft)->getSocket() and (*ft)->!DecrRef()? Other threads should
not have corrupted it because this thread's stack is not accessible to
other threads. In any case, the call is surrounded by
m_sockListLock.lockForWrite() and m_sockListLock.unlock() which ensures
single threading through this code.
ft is type iterator of <!FileTransfer * > and is effectively !FileTransfer
* *.
--
Ticket URL: <https://code.mythtv.org/trac/ticket/13598>
MythTV <http://www.mythtv.org>
MythTV Media Center
------------------------------------+--------------------------
Reporter: Peter Bennett | Owner: (none)
Type: Bug Report - Crash | Status: new
Priority: minor | Milestone: needs_triage
Component: MythTV - General | Version: Master Head
Severity: medium | Keywords:
Ticket locked: 0 |
------------------------------------+--------------------------
This happened twice on my development master backend, when looking at
program listings from the frontend and mythweb.
This is the log at the time
{{{
2020-02-15 14:39:26.894643 I MainServer: adding: andromeda(55971de35910)
as a file transfer
2020-02-15 14:39:26.897840 I MainServer: adding: andromeda(55971de34680)
as a file transfer
2020-02-15 14:39:26.897845 I FileTransfer sock(55971de37a70) disconnected
Handling Segmentation fault
Segmentation fault (core dumped)
}}}
Here is the relevant part of the backtrace. The segfault is in thread 1 in
code that is called from QT event processors.
{{{
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055971c7a3bab in MainServer::connectionClosed
(this=0x55971dd2ee00, socket=0x55971de37a70) at mainserver.cpp:7896
7896 (*ft)->DecrRef();
[Current thread is 1 (Thread 0x7ff91cbe9700 (LWP 10763))]
Thread 1 (Thread 0x7ff91cbe9700 (LWP 10763)):
#0 0x000055971c7a3bab in MainServer::connectionClosed(MythSocket*)
(this=0x55971dd2ee00, socket=0x55971de37a70) at mainserver.cpp:7896
sock = 0x55971de37a70
ft = 0x0
__FUNCTION__ = "connectionClosed"
cs = {i = {i = 0x7ff9698c2d20
<QSocketNotifier::setEnabled(bool)+144>}}
#1 0x00007ff96c085fe8 in MythSocket::DisconnectHandler()
(this=0x55971de37a70) at mythsocket.cpp:265
__FUNCTION__ = "DisconnectHandler"
#2 0x00007ff96c1cf885 in MythSocket::qt_static_metacall(QObject*,
QMetaObject::Call, int, void**) (_o=0x55971de37a70,
_c=QMetaObject::InvokeMetaMethod, _id=4, _a=0x7ff91cbe88c0) at
moc/moc_mythsocket.cpp:148
_t = 0x55971de37a70
}}}
This is the code around the segfault location [(*ft)->!DecrRef() is the
line which got the seg fault]
{{{
for (auto ft = m_fileTransferList.begin(); ft != m_fileTransferList.end();
++ft)
{
MythSocket *sock = (*ft)->getSocket();
if (sock == socket)
{
LOG(VB_GENERAL, LOG_INFO, QString("FileTransfer sock(%1)
disconnected")
.arg(quintptr(socket),0,16) );
(*ft)->DecrRef();
m_fileTransferList.erase(ft);
m_sockListLock.unlock();
UpdateSystemdStatus();
return;
}
}
}}}
In one backtrace ft was 0 and in the other it has a good looking value,
but examining the !FileTransfer structure it points to gives garbage, for
example the !FileTransfer m_sock object accesses an invalid location and
some boolean variables have values like 114 instead of true or false.
My dilemma is: How can ft (a variable on the stack) be corrupted between
the call to (*ft)->getSocket() and (*ft)->!DecrRef()? Other threads should
not have corrupted it because this thread's stack is not accessible to
other threads. In any case, the call is surrounded by
m_sockListLock.lockForWrite() and m_sockListLock.unlock() which ensures
single threading through this code.
ft is type iterator of <!FileTransfer * > and is effectively !FileTransfer
* *.
--
Ticket URL: <https://code.mythtv.org/trac/ticket/13598>
MythTV <http://www.mythtv.org>
MythTV Media Center