qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Help with deadlock when using sound


From: Programmingkid
Subject: Re: [Qemu-devel] Help with deadlock when using sound
Date: Tue, 12 May 2015 23:23:02 -0400


On May 12, 2015, at 3:45 AM, Paolo Bonzini wrote:

On 12/05/2015 00:43, Programmingkid wrote:

On May 10, 2015, at 10:54 AM, Paolo Bonzini wrote:



On 06/05/2015 18:40, Programmingkid wrote:
When I try to use the pcspk sound hardware, QEMU freezes and uses
100% of the cpu time. This is the command I use:

qemu-system-i386 -cdrom <anything you wan here> -soundhw pcspk

This looks like a deadlock situation because some unknown code called
qemu_mutex_lock(). Here is the stack trace at the freeze:

(gdb) bt #0  0x00007fff824e2db6 in semaphore_wait_trap () #1
0x00007fff824e8417 in pthread_mutex_lock () #2  0x0000000100267199 in
qemu_mutex_lock (mutex=<value temporarily unavailable, due to
optimizations>) at util/qemu-thread-posix.c:73 #3  0x003c44016e95153b
in ?? ()

My host is Mac OS 10.6.8. My guest isn't really anything. I have used
Windows XP before but it isn't necessary to reproduce the problem.

The ?? is what appears to be the problem. I can't even print
instructions at that address. Any ideas as to what is calling the
qemu_mutex_lock() function could help.

The unknown code here is probably some place where gdb cannot find the
frame pointer.  Not a surprise if you are using a 5 year old debugger
with (presumably) a newer compiler.

Reproduced with a FreeDOS image from QEMU Advent Calendar.  It locks up
as soon as you type "beep".

It works with the PulseAudio and ALSA backends, but it doesn't with the
SDL backend, even on Linux.

Also, it deadlocks even with KVM enabled.

Paolo

OK, I see a pattern. SDL and CoreAudio both don't support audio input. Both of them have this code:
.voice_size_in  = 0

Alsa and PulseAudio do support audio input and work. Coincidence?

Yes.  Locking in SDL is completely broken.  sdl_callback runs with the
SDL audio lock taken, but then it waits on a semaphore so you cannot
call any other SDL audio function from the main thread.  As soon as you
do that, you get a deadlock.  I'm strongly tempted to just remove the
driver.

On the other hand, CoreAudio seems to be okay.  Can you try "thread
apply all bt full" from gdb?

Paolo

Found out why QEMU is deadlocking. It is because a mutex that has been unlocked over 20 times in a row is being locked. 

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_lock.html

According to the above link, if pthread_mutex_unlock() is called on a mutex that isn't locked, undefined behavior results. This means the mutex that has been unlocked so many times in a row cannot be trusted. There isn't a way to find out who owns a mutex on Mac OS X, so I made my own logging code to help find out what was going on. If you have access to Mac OS 10.6, you could try out this code by just pasting it in qemu-thread-posix.c:

// Debugging code

#define MAX_SIZE 100
int thread_dict[MAX_SIZE] = {0};
int mutex_dict[MAX_SIZE] = {0};

int addToDict(int id, int * a_dict)
{
    static int index = 0;
    if(index > 99) {
        printf("ERROR: too many threads to keep track of!\n");
        return -1;
    }
    a_dict[index] = id;
    index++;
    return index;
}

int getID(int origID, int* a_dict)
{
    int index;
    for (index = 0; index < MAX_SIZE; index++) {
        if(a_dict[index] == origID) {
            return index;
        }
    }
    return addToDict(origID, a_dict);
}

#include <sys/syscall.h>
void qemu_mutex_lock(QemuMutex *mutex)
{
    int err;
    static int count = 0;
    printf("Lock\tThread = %d\tMutex = %d\n", getID(syscall(SYS_thread_selfid), thread_dict), getID(&mutex, mutex_dict));

    

    err = pthread_mutex_lock(&mutex->lock);
    if (err)
        error_exit(err, __func__);
}

int qemu_mutex_trylock(QemuMutex *mutex)
{
    printf("Trying lock\tThread = %d\tMutex = %d\n", getID(syscall(SYS_thread_selfid), thread_dict), getID(&mutex, mutex_dict));
    return pthread_mutex_trylock(&mutex->lock);
}

void qemu_mutex_unlock(QemuMutex *mutex)
{
    int err;

    static int count = 0;
    printf("Unlock\tThread = %d\tMutex = %d\n", getID(syscall(SYS_thread_selfid), thread_dict), getID(&mutex, mutex_dict));

    err = pthread_mutex_unlock(&mutex->lock);
    if (err)
        error_exit(err, __func__);
}

Locking mutex 38 is where qemu-system-i386 seems to fail the most. 

To test the code, I just ran qemu with -soundhw pcspk. 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]