Mixxx 1.10.0 - 1.11.0 beta2 pre 3314 hang or crash on track load

Bug #1024621 reported by RAWRR on 2012-07-14
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Mixxx
Critical
Daniel Schürmann
1.10
Critical
Unassigned
1.11
Critical
Daniel Schürmann

Bug Description

Attached is my log from the most recent crash. This has happened several times during sets, even after restarting, and as one might guess, it suuuuucks. It has never happened when using the DidJiX liveCD, which I have for several long sets. That distro has other problems though, namely playing deck's track skipping on cue deck's track load, maybe due to it using a Mixxx version vulnerable to this bug: "http://<email address hidden>/msg02684.html", so I would prefer not to use it.

I'm running XP Pro SP3, 1.60ghz, 753mb, onboard SigmaTel audio running out to the speakers with a crappy $2.75 Hong Kong C-Media USB sound card to the headphones (the sound to the headphones skips but I don't report that as a bug because I figure it has to do with my weak hardware rather than Mixxx). However, when I had the crashes during sets, though I was using the same C-Media external USB sound card for headphones, my hardware was 1.4ghz single core with 2gb of memory, but also running XP Pro, though SP2. I think the audio out was just onboard Realtek.

My Mixxx music library points to my 16gb USB flash drive, and the crashes happen not immediately, they happen as much as an hour and as little as a half an hour into a set. This of course makes it difficult to test for repeatability, since I don't always have a half an hour or more to devote to loading track after track into Mixxx to see if it crashes :/

I don't recall this happening with the 1.9 and earlier releases, but, by coincidence, I have been doing more sets since 1.10 so I'm not entirely sure the version change is relevant. It could just be that I've never done as many and as long of sets before 1.10.

My psychic powers tell me that the USB drive has something to do with it. I can't justify that, sorry, psychic power is mysterious. I'll run some sets from the disk instead to see if the same happens, but since some sets pass just fine anyway, I'm not sure that can help with being conclusive.

I'm hoping to have some clues before my next set in a couple of weeks :'((

UPDATE 08/01:

Last night I did a set with the 1.11.0 beta2 pre 3314 build. I had done a 3 hour test set before the actual set, using the same hardware I would be using for the set, to determine if it would crash, and it did not. However, later that evening during the actual set Mixxx did indeed crash about 3 hours into it. I was able to hurriedly restart and only had about ten seconds of dead air, but in the rush could not recover the log file. Mixxx did not crash for the remaining hour or so of the set.

The other problem I had consistently during both the practice and the real set was that when loading tracks into the cue deck the playing deck would hang for a minute - not keep playing and lose sound, but actually stop for about half a second before resuming. This was happening while the cue deck waveforms were being generated on the screen; I was using the filtered - software renderer at a default zoom of 16.7% and a framerate of 30, which had proven to be the most stable settings thus far - all the other zooms or renderers hung the playing deck more frequently. I also noticed that files with bitrates below 192, which is what almost all of my files are, seemed to cause the hang more. Also, all of my files had been analyzed by Mixxx's new 1.11 bpm scanning beforehand because I'd heard the scan also pregenerates the waveforms, which I figured would help. Apparently not :/

As a punctuation, in the event that this all is a cpu spec issue, I'd like to make a request that lower spec computers like mine be accommodated in the development. I don't think 1.4ghz single core is absurdly weak even by today's standards, it seems reasonable to expect an application like Mixxx to play well with it. Turning off waveforms sucks, not having beatgrids sucks. Anyway, turning off waveforms doesn't even help completely since skins have mini waveforms for the video card to deal with regardless.

RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
description: updated
description: updated
description: updated
description: updated
description: updated
RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
RAWRR (rawrr) on 2012-07-14
summary: - Mixxx crashes on track load into cue deck (as opposed to playing deck)
+ Mixxx crashes on track load
description: updated
description: updated
summary: - Mixxx crashes on track load
+ Mixxx 1.10.0 and 1.10.1 both crash on track load
RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
description: updated

Sorry to clutter up the page with my edits, I didn't realize that would happen and I'll do them offline in the future.

description: updated
RAWRR (rawrr) on 2012-07-14
tags: added: mixxx
tags: added: cue suddenly usb
tags: added: 1.10 1.10.0 1.10.1
tags: added: quit quits
Changed in mixxx:
status: New → Incomplete
status: Incomplete → New
RAWRR (rawrr) on 2012-07-14
description: updated
description: updated
RAWRR (rawrr) on 2012-07-17
visibility: public → private
visibility: private → public
RJ Skerry-Ryan (rryan) on 2012-07-26
Changed in mixxx:
importance: Undecided → Critical
tags: added: segfault
removed: 1.10 1.10.0 1.10.1 load mixxx quit quits sudden suddenly track
RAWRR (rawrr) wrote :

Maybe unrelated, but since I've been trying to streamline and discovered ASIO and WDM-KS I now remember I wasn't using those at the times of the crashes, I was using DirectSound.

RAWRR (rawrr) on 2012-08-02
description: updated
RAWRR (rawrr) on 2012-08-02
description: updated
description: updated
RAWRR (rawrr) on 2012-08-02
description: updated
description: updated
RAWRR (rawrr) on 2012-08-02
summary: - Mixxx 1.10.0 and 1.10.1 both crash on track load
+ Mixxx 1.10.0 - 1.11 beta2 pre 3314 crash on track load
summary: - Mixxx 1.10.0 - 1.11 beta2 pre 3314 crash on track load
+ Mixxx 1.10.0 - 1.11.0 beta2 pre 3314 crash on track load
description: updated
RAWRR (rawrr) on 2012-08-02
description: updated
summary: - Mixxx 1.10.0 - 1.11.0 beta2 pre 3314 crash on track load
+ Mixxx 1.10.0 - 1.11.0 beta2 pre 3314 hang or crash on track load
jus (jus) wrote :

* Reproduce the issue (Mixxx crash)
* Do not close the "Application has stopped working" window
* Run Windows Task Manager (press Ctrl-Shift-Esc or right click in the bar at the bottom of the screen and select “Start Task Manager”)
* The Task manager will open
* Go to the Processes tab and right-click on the crashed process (mixxx.exe)
* Select the Create Dump File item

Attach the dump file (*.DMP) to the bug report. This might help a developer to debug the issue on Windows.

RAWRR (rawrr) wrote :

The last time the crash happened, there was no "Application has stopped working" window. Mixxx just vanished.

I run Process Explorer at all times; at the time of the crash, I took a fraction of a second to check running processes to make sure Mixxx wasn't running (to be certain there would not be multiple instances that might cause a conflict when restarting) and indeed Mixxx was not running. It had quit completely, even ASIO had vanished from my tray. It came back up with Mixxx after restart.

Also, the crashes, every time, happen after several hours. Its difficult to replicate as a result. I have, however, put a shortcut on my desktop to the Application Data\Mixxx folder and hope that next time I have the reflexes to copy the log file to the desktop before restarting.

I have also had this bug. I will grab the log file next time it occurs.

To me it seems like it is happening if a new waveform is being created (new MP3 that has not been previously analysed). I have stopped this bug from re-occuring by running a BPM analysis on my entire music collection.

RAWRR (rawrr) wrote :

I *also* think it has to do with the waveform creation (I stopped thinking it had to do with my USB media). However, as I described above, I had run the BPM analysis:

"Also, all of my files had been analyzed by Mixxx's new 1.11 bpm scanning beforehand because I'd heard the scan also pregenerates the waveforms, which I figured would help. Apparently not :/"

And it did not help, in my case. The current frontrunner among culprits in my scheme of guesses is that this is a combination of the waveform generation and the relatively slow hardware of my machine, the second most likely suspect seems like it could be a bug in the BPM analysis algorithm; my set skipped especially much on files with lower bitrates, which seems like it shouldn't happen.

RAWRR (rawrr) wrote :

Which version of Mixxx did you use to do the scanning beforehand?

RJ Skerry-Ryan (rryan) wrote :

Hi guys -- I'd love to make progress on this bug. When you end up crashing make sure to grab the Mixxx log file and post it here. RAWRR -- I checked out the log you posted earlier but it was a run of Mixxx that didn't crash so it doesn't contain information about previous runs that might have crashed.

Thanks to both of you for your help,
RJ

RAWRR (rawrr) wrote :

Will do. The venue I've been using traded out my night in favor of more college student friendly programming awhile ago, so I haven't been running long sets since my last post.

Still have the shortcut to the appropriate Documents and Settings subfolder on my desktop, so if and when it happens again I still plan to grab the logfile.

jus (jus) wrote :

Just came again across this bug while testing https://code.launchpad.net/~mixxxdevelopers/mixxx/sample-grid , which uses the latest code from lp:mixxx/1.11. This is the first time i had the issue on MacOSX 10.8.2. It seems to me that the occurrence of the bugs depends on whether the current session had a sample deck playing or not , similar to lp:1013768

The GUI hangs for while the audio continues to play in the background. The GUI recovers after some time and the waveform is visible in the Decks.

To reproduce:
* Start Mixxx
* Load and Play a track in the Sample Deck
* Drag and drop a Track to Deck 1 or 2, one of them hangs

Instruments said, time is wasted in WaveformRenderPreroll during hang (see image)

Changed in mixxx:
status: New → Confirmed
Changed in mixxx:
assignee: nobody → Daniel Schürmann (daschuer)
Daniel Schürmann (daschuer) wrote :

I was not able to reproduce the problem with Mixxx 1.11 but I was able to reproduce this with my trunk.

When loading a new track many unsafe things happens with the stored values from a track, some are reflecting the new track some are still reflecting the old track.

The hanging in WaveformRenderPreroll is caused by the fact that the pre roll is always rendered from the current position left border to start position. It stalled the GUI if it is up to render from an insane negative position.

While it is hard to reproduce the hanging, you can see often spot a mixed up waveform when loading a new track, caused by this issue.

The best long term solution would be to redactor the track change with a proper protection of all effected values.

For now, I am working on a patch, which
* makes WaveformRenderPreroll drawing only the visible polynoms
* Only render the Background when loading a track

@ Jus: If you like, we may change the waveform background into something showing that track loading is in progress.

Note: I refer to only the tiny moment when engineBuffer reads the track, just before the Analyser takes place.
(It might be quite long on Netbooks or poor HDs )

Changed in mixxx:
status: Confirmed → In Progress
RAWRR (rawrr) wrote :

I'm SO happy progress is being made with this bug. I just wanted to add that I was never using samples when the crashes happened, just loading decks. I may have had the track at a negative position though - I'm not sure what is meant by that.

Daniel Schürmann (daschuer) wrote :

The attached patch solves the problem.

jus (jus) wrote :

Thanks Daniel,
tested your patch and now track loading does not crash or hang anymore. Good work.

As for the visualizing the load process i think it is a nice touch but isn`t it obvious that something is in progress by drawing the waveform overview slowly while analyzing?

On my machines the visible part of the main waveforms are visible near instantly, even for tracks that have not been analyzed before. If this is an issue on slower machines, we might add a simple pre-loader animation.

RAWRR (rawrr) wrote :

At the risk of looking retarded for beating a dead horse, I feel that anything that can be done to accommodate slower/older hardware is essential to a stable and enthusiastic userbase. Waveform beginnings may queue instantly for you, but for me even that part takes 1-3 seconds depending on my machine.

Daniel Schürmann (daschuer) wrote :

Just created a bug for the visualizing Bug #1080734

Daniel Schürmann (daschuer) wrote :

committed to lp:mixxx/1.11 #3484.

Set bug for 1.10 to won't fix because it is unlikely that we will ever make Mixxx 1.10.2, correct?

RJ Skerry-Ryan (rryan) wrote :

Nice work Daniel! I have some questions:

I took a look at the changes and I'd like to understand the engine changes a bit more. I see you delay the loading of tracks on the CueControl. Is this because the waveform would render the cues way offscreen which can cause graphics glitches / crashes? If that is the problem, couldn't we fix the mark-renderers instead?

About using -1 playposition to mean "no track loaded" I think we should be careful since a lot of MIDI scripts and other parts of Mixxx use the playposition value and might not expect an odd number. Is it enough to just set track_samples to 0 when a track is not loaded and then in the waveforms always make sure we have valid track_samples values? I think your changes already make the waveforms not render when track_samples is zero.

It strikes me that the engine changes here are really just compensating for lack of error handling in the waveforms. Do you agree? The engine code is already very complex so I'd prefer to keep it as simple as possible. Also, the engine-control-refactor branch changes the engine so that it's all single-threaded and lock-free. The call to CueControl from the engine worker thread won't be safe anymore in that case.

RJ Skerry-Ryan (rryan) wrote :

Also, yes WontFix for 1.10.x is right.

Daniel Schürmann (daschuer) wrote :

Hi RJ,

thank you for your review!

> .. delay the loading of tracks on the CueControl ..

I think you refer to my changes in EngineBuffer::slotTrackLoaded. The intention was to prevent the track to be loaded at position 0 and the seek to cue position. Now the track is loaded instantly at at cue position. I think this will not put an additional delay on loading tracks because CueControl::loadTrack was called from the GUI thread just after EngineBuffer::slotTrackLoaded and before the track was is playable.

> .. using -1 playposition ..

"track_samples" = 0 is no reliable indicator to detect that no track is loaded, because EngineBuffer::slotTrackLoaded() sets
"track_samples" to a valid value but "visual_playposition" was still pointing to the playposition of the track loaded before.
"visual_playposition" is reliable after seeking to cue point and after the next EngineBuffer::process() cycle.

In my work for waveform de-jerking in daschuers_trunk I have discard "visual_playposition" in favour of a VisualPlayPosition class
which is designed to sync sound output with the waveform display and deals with the limitations of the Qt event queue.

Do we need such a high precise "visual_playposition" CO for MIDI as well or is it enough for now to refer to the "playposition" CO for Midi?

> .. lack of error handling in the waveforms. ..

For me, my changes are fixing the root bug of this problem as explained above. In engine-control-refactor branch you have moved EngineBuffer::slotTrackLoaded to the Engine thread. When merging, we have to ensure that CueControl::loadTrack is still called from the engine worker pool.

Kind regards,

Daniel

Changed in mixxx:
status: In Progress → Fix Committed
RJ Skerry-Ryan (rryan) wrote :

Hi Daniel,

Here's a fix that I've written that doesn't require separating the CueControl from the rest. The main changes are:

* CueControl had signals connected from BaseTrackPlayer. This predates the introduction of the EngineBuffer trackLoaded/trackUnloaded signals which are not emitted from the GUI thread. In this patch I remove the other signal from the GUI thread / BaseTrackPlayer and replace it with the trackLoaded/trackUnloaded signals from EngineBuffer. Using these EngineBuffer signals accomplishes the same thing that you did by making CueControl::loadTrack return a double and be called from EngineBuffer::slotTrackLoaded. trackLoaded/trackUnloaded calls are DirectConnection slotted to the CueControl and other EngineControls. Seek requests emitted by the CueControl are DirectConnection slotted to EngineBuffer::slotControlSeekAbs so the seek to the load cue happens without roundtrips through the Qt event loop.

* In EngineBuffer::slotLoadTrack I have switched the loading flag to be a QAtomicInt instead of a bool so that memory fences are used and we don't need to use a mutex. I removed the track_samples set from there.

* If a track load has been requested, in EngineBuffer::process() I set the track samples and track samplerate to 0. This avoids having to use a COT in the EngineBuffer::slotLoadTrack.

Since I can't reproduce the issue, could you please test the patch to verify whether the bug is still fixed or not? I think the patch is mostly identical in behavior but it keeps things simpler since CueControl just uses the standard signals that EngineBuffer uses.

Daniel Schürmann (daschuer) wrote :

Hi RJ,

thank you for your patch, it includes the ideas that where missing in my patch. It really looks like that we are now able to fix the whole track change procedure.

I have modified you patch a little bit to iron out some remaining issues.
* CueControl::trackLoaded emits seekAbs in any case to overwrite the position from the previous track
* m_iTrackLoading is set to 0 not before all EngineControls are setup with the new track. This ensures that the track is properly seeked when the new buffer is processed.
* m_pTrackSamples has to be set to 0 in EgineBuffer::slotLoadTrack because of the other changes
* the m_pause.lock() in EgineBuffer::slotLoadTrack ensures that the buffer is not processed when starting to change the track

See attached.

Download full text (3.3 KiB)

On Wed, Nov 28, 2012 at 4:06 PM, Daniel Schürmann <
<email address hidden>> wrote:

> * CueControl::trackLoaded emits seekAbs in any case to overwrite the
> position from the previous track
>

Ah, looks good.

> * m_iTrackLoading is set to 0 not before all EngineControls are setup with
> the new track. This ensures that the track is properly seeked when the new
> buffer is processed.
>

I see.. looks good to me.

> * m_pTrackSamples has to be set to 0 in EgineBuffer::slotLoadTrack
> because of the other changes
> * the m_pause.lock() in EgineBuffer::slotLoadTrack ensures that the buffer
> is not processed when starting to change the track
>

Hm. I removed the track_samples set from slotLoadTrack so that we would not
edit track_samples while an EngineBuffer::process was in the middle of
running. I moved the set to the beginning of EngineBuffer::process() so
that if it was in the middle of running it would clear track_samples /
track_samplerate on the next callback. If EngineBuffer::process is not in
the middle of running then the m_iTrackLoading flag is sufficient to
prevent it from processing in the future.

So since EngineBuffer::slotLoadTrack in my version did nothing more than
set the m_iTrackLoading flag and request the buffer to stop playing I don't
think there is a danger of changing EngineBuffer values while it is in the
middle of processing.

The problem I wanted to avoid with using the m_pause lock in slotLoadTrack
is that it can block the GUI thread for the length of time it takes
EngineBuffer::process() to complete (at worst a few milliseconds on slow
hardware). This might not be perceptible to a user but it could cause the
Qt event loop to get behind in processing events and drawing the UI which
can impact Mixxx's GUI responsiveness.

Making changes in EngineBuffer::slotLoadTrack isn't the right place IMO
because all that method does is make the request to CachingReader to load
the track. The request is put in a queue and won't be processed until the
CachingReader thread wakes up and loads the track. I think it makes sense
to tell EngineBuffer to stop processing via the m_iTrackLoading flag and to
stop playing via the 'play' ControlObjectThread, but nothing more at that
point since no EngineControls will be updated with the new track until
EngineBuffer::slotTrackLoaded is signalled from the CachingReader that the
track has been successfully loaded.

Now that I look at BaseTrackPlayer::slotLoadTrack, I realize some logic in
that method is done on the assumption the track is already loaded when
that's not true since we're just about to submit the request to
EngineBuffer/CachingReader to load the track. The things it does are:

1) Save the loop in a loop cue on the currently loaded track (so the loop
can be loaded when the track is next loaded)
2) Set replaygain to 0
3) Emit unloadingTrack (does nothing since CueControl won't listen to that
signal anymore)
4) Set m_pLoadedTrack to the new track
5) Connect bpmupdated / replaygain-updated signals to the new track

So these 5 things aren't that bad in terms of causing out-of-sync values.

In general I think BaseTrackPlayer does a lot of logic that should be
handled by the Engine...

Read more...

Daniel Schürmann (daschuer) wrote :

Hi RJ,

> the m_pause.lock() in EgineBuffer::slotLoadTrack

Ok, I Understand. I will prepare a solution which just starts the caching reader. The caching reader will then call a callback from EgineBuffer at the start of CachingReader::loadTrack(TrackPointer pTrack).
So Engine Buffer can set m_pause.lock() and set m_pTrackSamples to 0 from the engine Worker thread, without locking GUI.

I will also change the m_trackQueue in CachingReader to a single TrackPionter, what it actually is.

Daniel Schürmann (daschuer) wrote :

Here it is

RJ Skerry-Ryan (rryan) wrote :

Good call on the queue in CachingReader. I wasn't thinking :).

v3 looks good.. please commit it!

* In EngineBuffer I think we can get rid of playButtonCOT and just use playButton since it's no longer in the main thread and playButtonCOT is a ControlObjectThreadMain. All the other uses of playButton might come from other threads so it seems to be fine anyway.

* EngineControl needs an empty slotTrackLoading method added since you connect that signal in EngineBuffer::addControl(). Or you could remove that connect() until we need to use that signal in an EngineControl.

Daniel Schürmann (daschuer) wrote :

commited to lp:mixxx/1.11 #3536.

RJ Skerry-Ryan (rryan) on 2013-05-09
Changed in mixxx:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers