QtAVPlayer
QtAVPlayer copied to clipboard
Possible rare crash in avcodec_send_packet() ?
In general the player code runs for days without issues, no leak, no crash. However occasionally there is a crash, freeing memory which was not allocated, and it seems to be in the av freeing methods, and also in avcodec_send_packet(). (It might have to do with unclean input data.)
While debugging, I stumbled over this:
in qavdemuxer.cpp
line 605, at QAVDemuxer::read()
if av_read_frame()
returns an error, and if the error is not EOF, an empty, uninitialized QAVPacket / AVPacket is used in the following processing and avcodec_send_packet() ?
QAVPacket pkt;
locker.unlock();
int ret = av_read_frame(d->ctx, pkt.packet());
if (ret < 0) {
if (ret == AVERROR_EOF || avio_feof(d->ctx->pb)) {
locker.relock();
d->eof = true;
locker.unlock();
}
}
locker.relock();
...
The crash is not often enough, so I'm not sure yet if the code above (ret
< 0 but not eof) is indeed a problem. (I have currently 3 PCs running trying to reproduce, and 2 of them didn't show it again for the last 2 days.)
One iMac just caught a crash, after running for about 48 hours without any issues. Apparently in av_frame_unref. Here the relevant parts of the MacOS crash report:
Crashed Thread: 13 QThread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
abort() called
MyPlayer(36284,0x7000107dc000) malloc: *** error for object 0x7fad1497df68: pointer being freed was not allocated
Thread 13 Crashed:: QThread
0 libsystem_kernel.dylib 0x00007fff2047b90e __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff204aa5bd pthread_kill + 263
2 libsystem_c.dylib 0x00007fff203ff406 abort + 125
3 libsystem_malloc.dylib 0x00007fff202df165 malloc_vreport + 548
4 libsystem_malloc.dylib 0x00007fff202e22aa malloc_report + 151
5 libavutil.58.dylib 0x000000010823e092 av_frame_unref + 146
6 org.qt-project.QtCore 0x000000010c43a738 QMetaType::destroy(void*) const + 72
7 org.qt-project.QtCore 0x000000010c45d992 QMetaCallEvent::~QMetaCallEvent() + 114
8 org.qt-project.QtCore 0x000000010c45da4e QMetaCallEvent::~QMetaCallEvent() + 14
9 org.qt-project.QtCore 0x000000010c419cd3 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 1491
10 org.qt-project.QtCore 0x000000010c5a6c1b QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 75
11 org.qt-project.QtCore 0x000000010c422616 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 486
12 org.qt-project.QtCore 0x000000010c50872a QThread::exec() + 298
13 org.qt-project.QtCore 0x000000010c5ab179 0x10c394000 + 2191737
14 libsystem_pthread.dylib 0x00007fff204aa8fc _pthread_start + 224
15 libsystem_pthread.dylib 0x00007fff204a6443 thread_start + 15
Thread 13 crashed with X86 Thread State (64-bit):
rax: 0x0000000000000000 rbx: 0x00007000107dc000 rcx: 0x00007000107dbb08 rdx: 0x0000000000000000
rdi: 0x000000000000d107 rsi: 0x0000000000000006 rbp: 0x00007000107dbb30 rsp: 0x00007000107dbb08
r8: 0x0000000000000000 r9: 0x0000000000000000 r10: 0x0000000000000000 r11: 0x0000000000000246
r12: 0x000000000000d107 r13: 0x0000000000000050 r14: 0x0000000000000006 r15: 0x0000000000000016
rip: 0x00007fff2047b90e rfl: 0x0000000000000246 cr2: 0x0000000111f62000
Logical CPU: 0
Error Code: 0x02000148
Trap Number: 133
Update:
After I added handling of av_read_frame() returning error (which is not eof), there are no more crashes on windows, despite the player running for more than a week non stop.
On Mac there are still crashes from time to time, with always a quite minimal report like this:
Crashed Thread: 37 Thread (pooled)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000
Termination Reason: Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process: exc handler [58190]
...
Thread 37 Crashed:: Thread (pooled)
0 ??? 0x0 ???
1 libavutil.58.dylib 0x10bd0fef7 0x10bd04000 + 48887
This happens sometimes after an hour, and sometimes after a day running non stop.
I will continue to research.
uninitialized QAVPacket / AVPacket is used in the following processing and avcodec_send_packet() ?
looks you are right, thanks, hope it is the same as you got on mac too
did you print out result of av_read_frame? why it failed
https://github.com/valbok/QtAVPlayer/pull/465