QAudioOutput and QAudioInput on linux with ALSA



  • Hello,
    I'm writing a simple VoIP application, and by now it runs very well on Windows, while on Linux (I'm using 3.18.6-1-ARCH, gcc 4.9.2) I have no choice but build it against Qt5, start the PulseAudio daemon, and select the devices shown in this picture, otherwise as soon as I do some UI interaction it soon crashes.
    If I use QAudioOutput in "push mode", I get SIGSEGV when I write to the QIODevice returned by QAudioOutput::start(), at this line:

    m_pushoutput->write(m_pushbuff.constData(), len);
    

    in the audiooutpanel.cpp file (line 312);
    if I use QAudioOutput in "pull mode", after a while the application freezes.

    I further investigated, compiled a debug version of Qt 4.8.6, and found that, when the system sends SIGSGV, the debugger stops at this line:

    int space = bytesFree();
    

    in the QAudioOutputPrivate::write function of the qaudiooutput_alsa_p.cpp file of the qt 4.8.6 source (11 lines below):

    qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
    {
    	// Write out some audio data
    	if ( !handle )
    		return 0;
    #ifdef DEBUG_AUDIO
    	qDebug()<<"frames to write out = "<<
    		snd_pcm_bytes_to_frames( handle, (int)len )<<" ("<<len<<") bytes";
    #endif
    	int frames, err;
    	int space = bytesFree();
    	if(len < space) {
    		// Just write it
    		frames = snd_pcm_bytes_to_frames( handle, (int)len );
    		err = snd_pcm_writei( handle, data, frames );
    	} else {
    		// Only write space worth
    		frames = snd_pcm_bytes_to_frames( handle, (int)space );
    		err = snd_pcm_writei( handle, data, frames );
    	}
    	if(err > 0) {
    		totalTimeValue += err;
    		resuming = false;
    		errorState = QAudio::NoError;
    		if (deviceState != QAudio::ActiveState) {
    			deviceState = QAudio::ActiveState;
    			emit stateChanged(deviceState);
    		}
    		return snd_pcm_frames_to_bytes( handle, err );
    	} else
    		err = xrun_recovery(err);
    
    	if(err < 0) {
    		close();
    		errorState = QAudio::FatalError;
    		deviceState = QAudio::StoppedState;
    		emit stateChanged(deviceState);
    	}
    	return 0;
    }
    

    Thanks for any help.

    PS: also I don't seem to find a way to succesfully build qt 4.8.6 with full PulseAudio support as QAudioDeviceInfo::availableDevices only returns two items ("system default" and "default"); this is the last configuration I've tryed:

    ./configure -platform linux-g++ -static -debug -prefix /home/tilly/BIN/qt-4.8.6-debug -qt-sql-sqlite -multimedia -audio-backend -system-nas-sound -no-openssl -no-qt3support -no-xmlpatterns -no-webkit -no-javascript-jit -no-script -no-scripttools -no-declarative -no-declarative-debug -no-nis -no-cups -nomake demos -nomake examples -nomake tools

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Do you have the PulseAudio development package installed ? You can also run configure with the -v option to see why the detection fails.

    As for the crashes, can you run your application with a debug build ?



  • Hi, thank you for your quick and kind reply :)

    I've run configure with the -v option, this is the output as for PulseAudio:

    PulseAudio auto-detection... ()
    g++ -c -pipe -D_REENTRANT -g -Wall -W  -I../../../mkspecs/linux-g++ -I. -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -o pulseaudio.o pulseaudio.cpp
    g++ -Wl,-rpath,/home/tilly/BIN/qt-4.8.6-debug/lib -o pulseaudio pulseaudio.o     -lpulse-mainloop-glib -lpulse -lglib-2.0 
    PulseAudio enabled.
    

    So it seems it's been detected.
    I'm not aware of any PulseAudio development package on ARCH linux, anyway I checked that the folder /usr/include/pulse is present in my system, and contains the pulseaudio header files, but I don't know if this is sufficient. Should I download something else?

    As for the crashes, yes I run the app with the debug build (of Qt, right?) and, as I wrote, while with the release build I got stuck in the

    m_pushoutput->write(m_pushbuff.constData(), len);
    

    line of my code (where m_pushoutput is the QIODevice returned by calling QAudioOutput::start()), with the debug build the SIGSEGV is emitted at this line:

    int space = bytesFree();
    

    in the qaudiooutput_alsa_p.cpp file of the qt 4.8.6 sources.

    To be more precise crashes happens randomly, for example, right after I click on a combo (before changing selection), when both audioinput and adiooutput are processing audio. The same thing (even worst) happens with Qt5, but in that case, when I select the "alsa_input" and "alsa_output" devices as shown here, it runs smoothly.

    As it stops before entering the bytesAvailable() function, it looks like a stack overflow or something, but I don't know how to further investigate.


  • Lifetime Qt Champion

    To look a bit further down, run a debug build of Qt and your software so you can grab some more information



  • Dear SGainst, I did run a debug build of Qt (v4.8.6) and my software, and found that where the program crashes each time is at this instruction at line 525 of the qtaudiooutput_pulse_p.cpp Qt 4.8.6 source file:

    int space = bytesFree();
    

    that is found inside this function (10 lines below definition):

    qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
    {
    	// Write out some audio data
    	if ( !handle )
    		return 0;
    #ifdef DEBUG_AUDIO
    	qDebug()<<"frames to write out = "<<
    		snd_pcm_bytes_to_frames( handle, (int)len )<<" ("<<len<<") bytes";
    #endif
    	int frames, err;
    	int space = bytesFree();
    	if(len < space) {
    		// Just write it
    		frames = snd_pcm_bytes_to_frames( handle, (int)len );
    		err = snd_pcm_writei( handle, data, frames );
    	} else {
    		// Only write space worth
    		frames = snd_pcm_bytes_to_frames( handle, (int)space );
    		err = snd_pcm_writei( handle, data, frames );
    	}
    	if(err > 0) {
    		totalTimeValue += err;
    		resuming = false;
    		errorState = QAudio::NoError;
    		if (deviceState != QAudio::ActiveState) {
    			deviceState = QAudio::ActiveState;
    			emit stateChanged(deviceState);
    		}
    		return snd_pcm_frames_to_bytes( handle, err );
    	} else
    		err = xrun_recovery(err);
    
    	if(err < 0) {
    		close();
    		errorState = QAudio::FatalError;
    		deviceState = QAudio::StoppedState;
    		emit stateChanged(deviceState);
    	}
    	return 0;
    }
    

    Since there are no variables read/write/dereferencing at that point, I thought it can probably be a stack overflow(?), but I don't actually know how to interpret/fix this. Here's the Disassembler view at eip:

    		516 [1]	{
    0x80be742                   55                    push   %ebp
    0x80be743  <+0x0001>        89 e5                 mov    %esp,%ebp
    0x80be745  <+0x0003>        57                    push   %edi
    0x80be746  <+0x0004>        56                    push   %esi
    0x80be747  <+0x0005>        53                    push   %ebx
    0x80be748  <+0x0006>        83 ec 2c              sub    $0x2c,%esp
    0x80be74b  <+0x0009>        e8 a0 45 f9 ff        call   0x8052cf0 <__x86.get_pc_thunk.bx>
    0x80be750  <+0x000e>        81 c3 ac 57 e2 00     add    $0xe257ac,%ebx
    0x80be756  <+0x0014>        8b 45 10              mov    0x10(%ebp),%eax
    0x80be759  <+0x0017>        89 45 d0              mov    %eax,-0x30(%ebp)
    0x80be75c  <+0x001a>        8b 45 14              mov    0x14(%ebp),%eax
    0x80be75f  <+0x001d>        89 45 d4              mov    %eax,-0x2c(%ebp)
    		518 [1]	    if ( !handle )
    0x80be762  <+0x0020>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be765  <+0x0023>        8b 40 78              mov    0x78(%eax),%eax
    0x80be768  <+0x0026>        85 c0                 test   %eax,%eax
    0x80be76a  <+0x0028>        75 0f                 jne    0x80be77b <QAudioOutputPrivate::write(char const*, long long)+57>
    		519 [1]	        return 0;
    0x80be76c  <+0x002a>        b8 00 00 00 00        mov    $0x0,%eax
    0x80be771  <+0x002f>        ba 00 00 00 00        mov    $0x0,%edx
    0x80be776  <+0x0034>        e9 65 01 00 00        jmp    0x80be8e0 <QAudioOutputPrivate::write(char const*, long long)+414>
    		525 [1]	    int space = bytesFree();
    0x80be77b  <+0x0039>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be77e  <+0x003c>        8b 00                 mov    (%eax),%eax
    0x80be780  <+0x003e>        83 c0 44              add    $0x44,%eax
    0x80be783  <+0x0041>        8b 00                 mov    (%eax),%eax
    0x80be785  <+0x0043>        83 ec 0c              sub    $0xc,%esp
    0x80be788  <+0x0046>        ff 75 08              pushl  0x8(%ebp)
    0x80be78b  <+0x0049>        ff d0                 call   *%eax
    0x80be78d  <+0x004b>        83 c4 10              add    $0x10,%esp
    0x80be790  <+0x004e>        89 45 e0              mov    %eax,-0x20(%ebp)
    		526 [1]	    if(len < space) {
    0x80be793  <+0x0051>        8b 45 e0              mov    -0x20(%ebp),%eax
    0x80be796  <+0x0054>        99                    cltd
    0x80be797  <+0x0055>        3b 55 d4              cmp    -0x2c(%ebp),%edx
    0x80be79a  <+0x0058>        7c 41                 jl     0x80be7dd <QAudioOutputPrivate::write(char const*, long long)+155>
    0x80be79c  <+0x005a>        3b 55 d4              cmp    -0x2c(%ebp),%edx
    0x80be79f  <+0x005d>        7f 05                 jg     0x80be7a6 <QAudioOutputPrivate::write(char const*, long long)+100>
    0x80be7a1  <+0x005f>        3b 45 d0              cmp    -0x30(%ebp),%eax
    0x80be7a4  <+0x0062>        76 37                 jbe    0x80be7dd <QAudioOutputPrivate::write(char const*, long long)+155>
    		528 [1]	        frames = snd_pcm_bytes_to_frames( handle, (int)len );
    0x80be7a6  <+0x0064>        8b 55 d0              mov    -0x30(%ebp),%edx
    0x80be7a9  <+0x0067>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be7ac  <+0x006a>        8b 40 78              mov    0x78(%eax),%eax
    0x80be7af  <+0x006d>        83 ec 08              sub    $0x8,%esp
    0x80be7b2  <+0x0070>        52                    push   %edx
    0x80be7b3  <+0x0071>        50                    push   %eax
    0x80be7b4  <+0x0072>        e8 e7 22 f9 ff        call   0x8050aa0 <snd_pcm_bytes_to_frames@plt>
    0x80be7b9  <+0x0077>        83 c4 10              add    $0x10,%esp
    0x80be7bc  <+0x007a>        89 45 dc              mov    %eax,-0x24(%ebp)
    		529 [1]	        err = snd_pcm_writei( handle, data, frames );
    0x80be7bf  <+0x007d>        8b 55 dc              mov    -0x24(%ebp),%edx
    0x80be7c2  <+0x0080>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be7c5  <+0x0083>        8b 40 78              mov    0x78(%eax),%eax
    0x80be7c8  <+0x0086>        83 ec 04              sub    $0x4,%esp
    0x80be7cb  <+0x0089>        52                    push   %edx
    0x80be7cc  <+0x008a>        ff 75 0c              pushl  0xc(%ebp)
    0x80be7cf  <+0x008d>        50                    push   %eax
    0x80be7d0  <+0x008e>        e8 1b 18 f9 ff        call   0x804fff0 <snd_pcm_writei@plt>
    0x80be7d5  <+0x0093>        83 c4 10              add    $0x10,%esp
    0x80be7d8  <+0x0096>        89 45 e4              mov    %eax,-0x1c(%ebp)
    0x80be7db  <+0x0099>        eb 34                 jmp    0x80be811 <QAudioOutputPrivate::write(char const*, long long)+207>
    		532 [1]	        frames = snd_pcm_bytes_to_frames( handle, (int)space );
    0x80be7dd  <+0x009b>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be7e0  <+0x009e>        8b 40 78              mov    0x78(%eax),%eax
    0x80be7e3  <+0x00a1>        83 ec 08              sub    $0x8,%esp
    0x80be7e6  <+0x00a4>        ff 75 e0              pushl  -0x20(%ebp)
    0x80be7e9  <+0x00a7>        50                    push   %eax
    0x80be7ea  <+0x00a8>        e8 b1 22 f9 ff        call   0x8050aa0 <snd_pcm_bytes_to_frames@plt>
    0x80be7ef  <+0x00ad>        83 c4 10              add    $0x10,%esp
    0x80be7f2  <+0x00b0>        89 45 dc              mov    %eax,-0x24(%ebp)
    		533 [1]	        err = snd_pcm_writei( handle, data, frames );
    0x80be7f5  <+0x00b3>        8b 55 dc              mov    -0x24(%ebp),%edx
    0x80be7f8  <+0x00b6>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be7fb  <+0x00b9>        8b 40 78              mov    0x78(%eax),%eax
    0x80be7fe  <+0x00bc>        83 ec 04              sub    $0x4,%esp
    0x80be801  <+0x00bf>        52                    push   %edx
    0x80be802  <+0x00c0>        ff 75 0c              pushl  0xc(%ebp)
    0x80be805  <+0x00c3>        50                    push   %eax
    0x80be806  <+0x00c4>        e8 e5 17 f9 ff        call   0x804fff0 <snd_pcm_writei@plt>
    0x80be80b  <+0x00c9>        83 c4 10              add    $0x10,%esp
    0x80be80e  <+0x00cc>        89 45 e4              mov    %eax,-0x1c(%ebp)
    		535 [1]	    if(err > 0) {
    0x80be811  <+0x00cf>        83 7d e4 00           cmpl   $0x0,-0x1c(%ebp)
    0x80be815  <+0x00d3>        7e 6d                 jle    0x80be884 <QAudioOutputPrivate::write(char const*, long long)+322>
    		536 [1]	        totalTimeValue += err;
    0x80be817  <+0x00d5>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be81a  <+0x00d8>        8b 70 28              mov    0x28(%eax),%esi
    0x80be81d  <+0x00db>        8b 78 2c              mov    0x2c(%eax),%edi
    0x80be820  <+0x00de>        8b 45 e4              mov    -0x1c(%ebp),%eax
    0x80be823  <+0x00e1>        99                    cltd
    0x80be824  <+0x00e2>        01 f0                 add    %esi,%eax
    0x80be826  <+0x00e4>        11 fa                 adc    %edi,%edx
    0x80be828  <+0x00e6>        8b 4d 08              mov    0x8(%ebp),%ecx
    0x80be82b  <+0x00e9>        89 41 28              mov    %eax,0x28(%ecx)
    0x80be82e  <+0x00ec>        89 51 2c              mov    %edx,0x2c(%ecx)
    		537 [1]	        resuming = false;
    0x80be831  <+0x00ef>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be834  <+0x00f2>        c6 40 1a 00           movb   $0x0,0x1a(%eax)
    		538 [1]	        errorState = QAudio::NoError;
    0x80be838  <+0x00f6>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be83b  <+0x00f9>        c7 40 10 00 00 00 00  movl   $0x0,0x10(%eax)
    		539 [1]	        if (deviceState != QAudio::ActiveState) {
    0x80be842  <+0x0100>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be845  <+0x0103>        8b 40 14              mov    0x14(%eax),%eax
    0x80be848  <+0x0106>        85 c0                 test   %eax,%eax
    0x80be84a  <+0x0108>        74 20                 je     0x80be86c <QAudioOutputPrivate::write(char const*, long long)+298>
    		540 [1]	            deviceState = QAudio::ActiveState;
    0x80be84c  <+0x010a>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be84f  <+0x010d>        c7 40 14 00 00 00 00  movl   $0x0,0x14(%eax)
    		541 [1]	            emit stateChanged(deviceState);
    0x80be856  <+0x0114>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be859  <+0x0117>        8b 50 14              mov    0x14(%eax),%edx
    0x80be85c  <+0x011a>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be85f  <+0x011d>        83 ec 08              sub    $0x8,%esp
    0x80be862  <+0x0120>        52                    push   %edx
    0x80be863  <+0x0121>        50                    push   %eax
    0x80be864  <+0x0122>        e8 a1 35 00 00        call   0x80c1e0a <QAbstractAudioOutput::stateChanged(QAudio::State)>
    0x80be869  <+0x0127>        83 c4 10              add    $0x10,%esp
    		543 [1]	        return snd_pcm_frames_to_bytes( handle, err );
    0x80be86c  <+0x012a>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be86f  <+0x012d>        8b 40 78              mov    0x78(%eax),%eax
    0x80be872  <+0x0130>        83 ec 08              sub    $0x8,%esp
    0x80be875  <+0x0133>        ff 75 e4              pushl  -0x1c(%ebp)
    0x80be878  <+0x0136>        50                    push   %eax
    0x80be879  <+0x0137>        e8 42 43 f9 ff        call   0x8052bc0 <snd_pcm_frames_to_bytes@plt>
    0x80be87e  <+0x013c>        83 c4 10              add    $0x10,%esp
    0x80be881  <+0x013f>        99                    cltd
    0x80be882  <+0x0140>        eb 5c                 jmp    0x80be8e0 <QAudioOutputPrivate::write(char const*, long long)+414>
    		545 [1]	        err = xrun_recovery(err);
    0x80be884  <+0x0142>        83 ec 08              sub    $0x8,%esp
    0x80be887  <+0x0145>        ff 75 e4              pushl  -0x1c(%ebp)
    0x80be88a  <+0x0148>        ff 75 08              pushl  0x8(%ebp)
    0x80be88d  <+0x014b>        e8 b4 e3 ff ff        call   0x80bcc46 <QAudioOutputPrivate::xrun_recovery(int)>
    0x80be892  <+0x0150>        83 c4 10              add    $0x10,%esp
    0x80be895  <+0x0153>        89 45 e4              mov    %eax,-0x1c(%ebp)
    		547 [1]	    if(err < 0) {
    0x80be898  <+0x0156>        83 7d e4 00           cmpl   $0x0,-0x1c(%ebp)
    0x80be89c  <+0x015a>        79 38                 jns    0x80be8d6 <QAudioOutputPrivate::write(char const*, long long)+404>
    		548 [1]	        close();
    0x80be89e  <+0x015c>        83 ec 0c              sub    $0xc,%esp
    0x80be8a1  <+0x015f>        ff 75 08              pushl  0x8(%ebp)
    0x80be8a4  <+0x0162>        e8 3f fd ff ff        call   0x80be5e8 <QAudioOutputPrivate::close()>
    0x80be8a9  <+0x0167>        83 c4 10              add    $0x10,%esp
    		549 [1]	        errorState = QAudio::FatalError;
    0x80be8ac  <+0x016a>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be8af  <+0x016d>        c7 40 10 04 00 00 00  movl   $0x4,0x10(%eax)
    		550 [1]	        deviceState = QAudio::StoppedState;
    0x80be8b6  <+0x0174>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be8b9  <+0x0177>        c7 40 14 02 00 00 00  movl   $0x2,0x14(%eax)
    		551 [1]	        emit stateChanged(deviceState);
    0x80be8c0  <+0x017e>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be8c3  <+0x0181>        8b 50 14              mov    0x14(%eax),%edx
    0x80be8c6  <+0x0184>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be8c9  <+0x0187>        83 ec 08              sub    $0x8,%esp
    0x80be8cc  <+0x018a>        52                    push   %edx
    0x80be8cd  <+0x018b>        50                    push   %eax
    0x80be8ce  <+0x018c>        e8 37 35 00 00        call   0x80c1e0a <QAbstractAudioOutput::stateChanged(QAudio::State)>
    0x80be8d3  <+0x0191>        83 c4 10              add    $0x10,%esp
    		553 [1]	    return 0;
    0x80be8d6  <+0x0194>        b8 00 00 00 00        mov    $0x0,%eax
    0x80be8db  <+0x0199>        ba 00 00 00 00        mov    $0x0,%edx
    		554 [1]	}
    0x80be8e0  <+0x019e>        8d 65 f4              lea    -0xc(%ebp),%esp
    0x80be8e3  <+0x01a1>        5b                    pop    %ebx
    0x80be8e4  <+0x01a2>        5e                    pop    %esi
    0x80be8e5  <+0x01a3>        5f                    pop    %edi
    0x80be8e6  <+0x01a4>        5d                    pop    %ebp
    0x80be8e7  <+0x01a5>        c3                    ret
    

    Can anyone explain/suggest a fix for that?
    Thanks a lot in advance


  • Lifetime Qt Champion

    Can you redo the build with DEBUG_AUDIO defined ? It might give some additional hints on what is going on



  • Hi, here we go :)

    After compiling with DEBUG_AUDIO I run the app, and got a long list of logs of what's appening, just before the app stops or hungs:

    37 s  236 ms :open() 
    37 s  359 ms :open() 
    defaults out of range 
    pmin= 21333 , pmax= 21334 , bmin= 42666 , bmax= 170667 
    used: buffer_time= 85332 , period_time= 21333 
    37 s  457 ms :userFeed() IN 
    read in bytes = 0 (frames=0) 
    37 s  460 ms :userFeed() OUT 
    frames to write out =  512  ( 1024 ) bytes 
    37 s  478 ms :updateAvailable() 
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    37 s  503 ms :updateAvailable() 
    37 s  509 ms :userFeed() OUT 
    37 s  524 ms :updateAvailable() 
    37 s  541 ms :updateAvailable() 
    37 s  544 ms :userFeed() IN 
    37 s  565 ms :updateAvailable() 
    37 s  566 ms :updateAvailable() 
    read in bytes = 1700 (frames=850) 
    frames to write to QIODevice =  850  ( 1700 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    37 s  683 ms :updateAvailable() 
    
    ... (long long list of similar logs) ...
    
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    39 s  10 ms :updateAvailable() 
    39 s  11 ms :userFeed() OUT 
    39 s  22 ms :updateAvailable() 
    39 s  26 ms :userFeed() OUT 
    39 s  36 ms :userFeed() IN 
    read in bytes = 680 (frames=340) 
    frames to write to QIODevice =  340  ( 680 ) bytes 
    39 s  44 ms :updateAvailable() 
    39 s  47 ms :userFeed() OUT 
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    39 s  66 ms :updateAvailable() 
    39 s  68 ms :userFeed() OUT 
    39 s  86 ms :updateAvailable() 
    39 s  89 ms :userFeed() IN 
    read in bytes = 1020 (frames=510) 
    frames to write to QIODevice =  510  ( 1020 ) bytes 
    39 s  99 ms :userFeed() OUT 
    39 s  116 ms :updateAvailable() 
    39 s  117 ms :userFeed() OUT 
    frames to write out =  512  ( 1024 ) bytes 
    frames to write out =  512  ( 1024 ) bytes 
    

    Actually I didn't find this very usefull, but if you wish I can send more and give you a more detailed description.

    What I've found really strange (I'm not used to read assembly at all) is that when the SIGSEGV occurs the eip points at line 0x80be783 in this fragment (4th line down):

    		525 [1]	    int space = bytesFree();
    0x80be77b  <+0x0039>        8b 45 08              mov    0x8(%ebp),%eax
    0x80be77e  <+0x003c>        8b 00                 mov    (%eax),%eax
    0x80be780  <+0x003e>        83 c0 44              add    $0x44,%eax
    0x80be783  <+0x0041>        8b 00                 mov    (%eax),%eax
    0x80be785  <+0x0043>        83 ec 0c              sub    $0xc,%esp
    0x80be788  <+0x0046>        ff 75 08              pushl  0x8(%ebp)
    0x80be78b  <+0x0049>        ff d0                 call   *%eax
    0x80be78d  <+0x004b>        83 c4 10              add    $0x10,%esp
    0x80be790  <+0x004e>        89 45 e0              mov    %eax,-0x20(%ebp)
    
    (see entire fragment in my previous answer)
    

    this seems to be a push in the stack just before calling "bytesFree()".
    But why is deferencing %eax and than calling *%eax is behond my understanding (in all other function call there is a fixed memory address).
    The really strange thing, hower, is that if I watch locals at that point:

    int frames, err;
    int space = bytesFree(); <-- stopped here
    

    while when stopped at breakpoint "frames", "err" and "space" contain just rubbish, as expected, when stopped after SIGSEGV they do have initialized values (usually frames=1, err=-77, space=320). Does this make any sense??

    However, as it seems that the device is stopped from some other thread while inside this function, I've slightly modified the qaudiooutput_asla_p.cpp Qt source file, and added a few checks just before trying to write to the audio device;
    here's the pach:

    522,525d519
    <     // tilly 20/04/2015: moved this two lines on top of function)
    <     if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
    <         return 0;
    < 
    529,530c523,524
    <     // tilly 20/04/2015: (see above)
    < 
    ---
    >     if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
    >         return 0;
    540,543d533
    <     // tilly 20/04/2015: added this two lines to check state before SIGEGV occurs!
    <     if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
    <         return 0;
    < 
    784,787d773
    <     // tilly 20/04/2015: added this two lines
    <     if(!audioDevice)
    <         return 0;
    < 
    792c778
    <         while(audioDevice && (written < len)) { // tilly 20/04/2015: added audioDevice test!
    ---
    >         while(written < len) {
    796,797c782
    <             else // tilly 20/04/2015: added else [if ever chunk<0 (as not excluded by the test before) - adding to written would result in a mess probably..]
    <                 written+=chunk;
    ---
    >             written+=chunk;
    

    As I link to Qt statically, this gave my app a reasonable level of stability, so if audio stops I can just print an error message, but any further explaination on the cause of the SIGSEGV would be much appreciated.
    What do you think about that?


  • Lifetime Qt Champion

    I'd check with all function modifying the state of the device to see if there's something unusual happening. Also I wonder if it's your device driver that is acting up.

    A quick check to the bug report system would also be a good idea


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.