valbok / QtAVPlayer

Free and open-source Qt Media Player library based on FFmpeg, for Linux, Windows, macOS, iOS and Android.
MIT License
282 stars 54 forks source link

Possible rare crash in avcodec_send_packet() ? #462

Closed geminixdev closed 4 months ago

geminixdev commented 5 months ago

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.)

geminixdev commented 5 months ago

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
geminixdev commented 4 months ago

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.

valbok commented 4 months ago

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

valbok commented 4 months ago

did you print out result of av_read_frame? why it failed

valbok commented 4 months ago

https://github.com/valbok/QtAVPlayer/pull/465