View Issue Details

IDProjectCategoryView StatusLast Update
0005871ardourbugspublic2014-05-17 20:46
Reporteraggraef Assigned To 
PrioritynormalSeveritycrashReproducibilityalways
Status newResolutionopen 
Summary0005871: Routing MIDI from one track to another trips assert `_capacity >= copy._size' failed in libs/ardour/midi_buffer.cc:76
DescriptionUsing ardour-3.5.357 (latest from git). This has been bugging me for a while already, but I don't know at which revision the crashes started. It is obviously related to routing MIDI from some MIDI tracks to another (commonly employed for bouncing or, in my case, having a single LV2 instrument plugin play back all the routed MIDI tracks. So this *might* be related to issue 0005302, but it's all about MIDI tracks in my case.)

To reproduce, open the attached session and press Play, then Stop.

Symptom: as soon as playback is stopped, Ardour crashes at the following assertion:

ardour-3.5.357: ../libs/ardour/midi_buffer.cc:76: void ARDOUR::MidiBuffer::copy(const ARDOUR::MidiBuffer&): Assertion `_capacity >= copy._size' failed.
Aborted (core dumped)

I'll also attach the full gdb backtrace so that you can see the entire call chain leading up to the assertion. (It's in Thread 19.)

I've been looking at the related MIDI buffering code myself, but couldn't find anything that's obviously wrong with it. Any suggestions on how I may help to debug the issue or fix it is appreciated.
Additional InformationNotes:

The session contains two snapshots: 1-nocrash contains the same 2 original MIDI tracks but without any routing inside Ardour; this plays back fine. 2-crash has the routing from MIDI tracks 1+2 set up to the third MIDI track, which crashes when playback stops.

I've added an LV2 instrument (Calf Organ) to the track so that there's actually something to listen to, but that it is immaterial. The same crash happens if there are no plugins at all on any of the tracks.
TagsNo tags attached.

Activities

2014-02-26 22:09

 

crashtest.tar.bz2 (12,462 bytes)

2014-02-26 22:10

 

crashtest-gdb-backtrace.txt (17,834 bytes)   
(gdb) thread apply all bt

Thread 22 (Thread 0x7fffd1031700 (LWP 12899)):
#0  0x00007ffff0aa9aad in nanosleep () from /usr/lib/libc.so.6
#1  0x00007ffff0ad1c14 in usleep () from /usr/lib/libc.so.6
#2  0x00007ffff72de18f in ARDOUR::AutomationWatch::thread() ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff72e195f in boost::_mfi::mf0<void, ARDOUR::AutomationWatch>::operator()(ARDOUR::AutomationWatch*) const () from /usr/lib/ardour3/libardour.so.3
#4  0x00007ffff72e15c2 in void boost::_bi::list1<boost::_bi::value<ARDOUR::AutomationWatch*> >::operator()<boost::_mfi::mf0<void, ARDOUR::AutomationWatch>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, ARDOUR::AutomationWatch>&, boost::_bi::list0&, int) () from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff72e113f in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AutomationWatch>, boost::_bi::list1<boost::_bi::value<ARDOUR::AutomationWatch*> > >::operator()() () from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff72e10ca in sigc::adaptor_functor<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AutomationWatch>, boost::_bi::list1<boost::_bi::value<ARDOUR::AutomationWatch*> > > >::operator()() const ()
   from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff72e0bfe in sigc::internal::slot_call0<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AutomationWatch>, boost::_bi::list1<boost::_bi::value<ARDOUR::AutomationWatch*> > >, void>::call_it(sigc::internal::slot_rep*) ()
   from /usr/lib/ardour3/libardour.so.3
#8  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#9  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#10 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#11 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 21 (Thread 0x7fffc3fff700 (LWP 12897)):
#0  0x00007ffff0acf87d in poll () from /usr/lib/libc.so.6
#1  0x00007ffff51bd584 in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff51bd9ea in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#3  0x00007ffff5e1044f in BaseUI::main_thread() ()
   from /usr/lib/ardour3/libpbd.so.4
#4  0x00007ffff5e13cb4 in sigc::bound_mem_functor0<void, BaseUI>::operator()() const () from /usr/lib/ardour3/libpbd.so.4
#5  0x00007ffff5e139f4 in sigc::adaptor_functor<sigc::bound_mem_functor0<void, BaseUI> >::operator()() const () from /usr/lib/ardour3/libpbd.so.4
#6  0x00007ffff5e133b1 in sigc::internal::slot_call0<sigc::bound_mem_functor0<void, BaseUI>, void>::call_it(sigc::internal::slot_rep*) ()
   from /usr/lib/ardour3/libpbd.so.4
#7  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#8  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#9  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#10 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 20 (Thread 0x7fffa407d800 (LWP 12896)):
#0  0x00007ffff0acf87d in poll () from /usr/lib/libc.so.6
#1  0x00007ffff72f1726 in ARDOUR::Butler::thread_work() ()
   from /usr/lib/ardour3/libardour.so.3
#2  0x00007ffff72f167f in ARDOUR::Butler::_thread_work(void*) ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff5e385c8 in ?? () from /usr/lib/ardour3/libpbd.so.4
#4  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#5  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 19 (Thread 0x7fff94087700 (LWP 12895)):
#0  0x00007ffff0a28369 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff0a29768 in abort () from /usr/lib/libc.so.6
#2  0x00007ffff0a21456 in __assert_fail_base () from /usr/lib/libc.so.6
#3  0x00007ffff0a21502 in __assert_fail () from /usr/lib/libc.so.6
#4  0x00007ffff7419bf7 in ARDOUR::MidiBuffer::copy(ARDOUR::MidiBuffer const&)
    () from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff755578e in ARDOUR::Route::fill_buffers_with_input(ARDOUR::BufferSet&, boost::shared_ptr<ARDOUR::IO>, unsigned int) ()
   from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff7689c1d in ARDOUR::Track::no_roll(unsigned int, long, long, bool) () from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff74701d3 in ARDOUR::MidiTrack::no_roll(unsigned int, long, long, bool) () from /usr/lib/ardour3/libardour.so.3
#8  0x00007ffff73bbeef in ARDOUR::Graph::process_one_route(ARDOUR::Route*) ()
   from /usr/lib/ardour3/libardour.so.3
#9  0x00007ffff73bfc68 in ARDOUR::GraphNode::process() ()
   from /usr/lib/ardour3/libardour.so.3
#10 0x00007ffff73ba898 in ARDOUR::Graph::run_one() ()
   from /usr/lib/ardour3/libardour.so.3
#11 0x00007ffff73baa8a in ARDOUR::Graph::helper_thread() ()
   from /usr/lib/ardour3/libardour.so.3
#12 0x00007ffff73bf5b5 in boost::_mfi::mf0<void, ARDOUR::Graph>::operator()(ARDOUR::Graph*) const () from /usr/lib/ardour3/libardour.so.3
#13 0x00007ffff73bf1ec in void boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> >::operator()<boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, ARDOUR::Graph>&, boost::_bi::list0&, int) () from /usr/lib/ardour3/libardour.so.3
#14 0x00007ffff73beefb in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >::operator()()
    () from /usr/lib/ardour3/libardour.so.3
#15 0x00007ffff73bea39 in boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >, void>::invoke(boost::detail::function::function_buffer&) () from /usr/lib/ardour3/libardour.so.3
#16 0x0000000000eae7e4 in boost::function0<void>::operator()() const ()
#17 0x00007fffe0ae9259 in ARDOUR::JACKAudioBackend::_start_process_thread(void*) () from /usr/lib/ardour3/backends/libjack_audiobackend.so
#18 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#19 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 18 (Thread 0x7fff94108700 (LWP 12894)):
#0  0x00007ffff1d1cff0 in sem_wait () from /usr/lib/libpthread.so.0
#1  0x00007ffff73bc11a in PBD::ProcessSemaphore::wait() ()
   from /usr/lib/ardour3/libardour.so.3
#2  0x00007ffff73ba753 in ARDOUR::Graph::run_one() ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff73baa8a in ARDOUR::Graph::helper_thread() ()
   from /usr/lib/ardour3/libardour.so.3
#4  0x00007ffff73bf5b5 in boost::_mfi::mf0<void, ARDOUR::Graph>::operator()(ARDOUR::Graph*) const () from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff73bf1ec in void boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> >::operator()<boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, ARDOUR::Graph>&, boost::_bi::list0&, int) () from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff73beefb in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >::operator()()
    () from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff73bea39 in boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >, void>::invoke(boost::detail::function::function_buffer&) () from /usr/lib/ardour3/libardour.so.3
#8  0x0000000000eae7e4 in boost::function0<void>::operator()() const ()
#9  0x00007fffe0ae9259 in ARDOUR::JACKAudioBackend::_start_process_thread(void*) () from /usr/lib/ardour3/backends/libjack_audiobackend.so
#10 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#11 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 17 (Thread 0x7fff94189700 (LWP 12893)):
#0  0x00007ffff1d1cff0 in sem_wait () from /usr/lib/libpthread.so.0
#1  0x00007ffff73bc11a in PBD::ProcessSemaphore::wait() ()
   from /usr/lib/ardour3/libardour.so.3
#2  0x00007ffff73ba753 in ARDOUR::Graph::run_one() ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff73bacb4 in ARDOUR::Graph::main_thread() ()
   from /usr/lib/ardour3/libardour.so.3
#4  0x00007ffff73bf5b5 in boost::_mfi::mf0<void, ARDOUR::Graph>::operator()(ARDOUR::Graph*) const () from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff73bf1ec in void boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> >::operator()<boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, ARDOUR::Graph>&, boost::_bi::list0&, int) () from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff73beefb in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >::operator()()
    () from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff73bea39 in boost::detail::function::void_function_obj_invoker0<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::Graph>, boost::_bi::list1<boost::_bi::value<ARDOUR::Graph*> > >, void>::invoke(boost::detail::function::function_buffer&) () from /usr/lib/ardour3/libardour.so.3
#8  0x0000000000eae7e4 in boost::function0<void>::operator()() const ()
#9  0x00007fffe0ae9259 in ARDOUR::JACKAudioBackend::_start_process_thread(void*) () from /usr/lib/ardour3/backends/libjack_audiobackend.so
#10 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#11 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 16 (Thread 0x7fffc1ad8700 (LWP 12890)):
#0  0x00007ffff1d1e12d in nanosleep () from /usr/lib/libpthread.so.0
#1  0x00007ffff51e3558 in g_usleep () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff7292882 in ARDOUR::AudioEngine::meter_thread() ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff729dac7 in boost::_mfi::mf0<void, ARDOUR::AudioEngine>::operator()(ARDOUR::AudioEngine*) const () from /usr/lib/ardour3/libardour.so.3
#4  0x00007ffff729d6d0 in void boost::_bi::list1<boost::_bi::value<ARDOUR::AudioEngine*> >::operator()<boost::_mfi::mf0<void, ARDOUR::AudioEngine>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, ARDOUR::AudioEngine>&, boost::_bi::list0&, int) () from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff729cfff in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AudioEngine>, boost::_bi::list1<boost::_bi::value<ARDOUR::AudioEngine*> > >::operator()() () from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff729c7ae in sigc::adaptor_functor<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AudioEngine>, boost::_bi::list1<boost::_bi::value<ARDOUR::AudioEngine*> > > >::operator()() const ()
   from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff729b8b6 in sigc::internal::slot_call0<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ARDOUR::AudioEngine>, boost::_bi::list1<boost::_bi::value<ARDOUR::AudioEngine*> > >, void>::call_it(sigc::internal::slot_rep*) ()
   from /usr/lib/ardour3/libardour.so.3
#8  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#9  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#10 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#11 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 15 (Thread 0x7fffd0141700 (LWP 12889)):
#0  0x00007ffff1d1cff0 in sem_wait () from /usr/lib/libpthread.so.0
#1  0x00007ffff73bc11a in PBD::ProcessSemaphore::wait() ()
   from /usr/lib/ardour3/libardour.so.3
#2  0x00007ffff73bbcba in ARDOUR::Graph::routes_no_roll(unsigned int, long, long, bool, int) () from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff7604507 in ARDOUR::Session::no_roll(unsigned int) ()
   from /usr/lib/ardour3/libardour.so.3
#4  0x00007ffff7604306 in ARDOUR::Session::fail_roll(unsigned int) ()
   from /usr/lib/ardour3/libardour.so.3
#5  0x00007ffff76077d9 in ARDOUR::Session::process_without_events(unsigned int)
    () from /usr/lib/ardour3/libardour.so.3
#6  0x00007ffff7605334 in ARDOUR::Session::process_with_events(unsigned int) ()
   from /usr/lib/ardour3/libardour.so.3
#7  0x00007ffff76041ce in ARDOUR::Session::process(unsigned int) ()
   from /usr/lib/ardour3/libardour.so.3
#8  0x00007ffff729255f in ARDOUR::AudioEngine::process_callback(unsigned int)
    () from /usr/lib/ardour3/libardour.so.3
#9  0x00007fffe0ae9312 in ARDOUR::JACKAudioBackend::process_thread() ()
   from /usr/lib/ardour3/backends/libjack_audiobackend.so
#10 0x00007fffe0ae92aa in ARDOUR::JACKAudioBackend::_process_thread(void*) ()
   from /usr/lib/ardour3/backends/libjack_audiobackend.so
#11 0x00007fffe0882f77 in ?? () from /usr/lib/libjack.so.0
#12 0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#13 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 14 (Thread 0x7fffc23d9700 (LWP 12887)):
#0  0x00007ffff1d1b03f in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /usr/lib/libpthread.so.0
#1  0x00007fffe0884473 in ?? () from /usr/lib/libjack.so.0
#2  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#3  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 12 (Thread 0x7fffc35f8700 (LWP 12885)):
#0  0x00007ffff1d1b3e8 in pthread_cond_timedwait@@GLIBC_2.3.2 ()
   from /usr/lib/libpthread.so.0
#1  0x00007ffff51fd5d5 in g_cond_wait_until () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff5193d51 in ?? () from /usr/lib/libglib-2.0.so.0
#3  0x00007ffff51942db in g_async_queue_timeout_pop ()
   from /usr/lib/libglib-2.0.so.0
#4  0x00007ffff51e2a46 in ?? () from /usr/lib/libglib-2.0.so.0
#5  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#6  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#7  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 7 (Thread 0x7fffd1832700 (LWP 12879)):
#0  0x00007ffff0acf87d in poll () from /usr/lib/libc.so.6
#1  0x00007ffff51bd584 in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff51bd68c in g_main_context_iteration ()
   from /usr/lib/libglib-2.0.so.0
#3  0x00007ffff51bd6d9 in ?? () from /usr/lib/libglib-2.0.so.0
#4  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#5  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#6  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 6 (Thread 0x7fffd2033700 (LWP 12878)):
#0  0x00007ffff0acf87d in poll () from /usr/lib/libc.so.6
#1  0x00007ffff51bd584 in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff51bd9ea in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#3  0x00007fffed297176 in ?? () from /usr/lib/libgio-2.0.so.0
#4  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#5  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#6  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 5 (Thread 0x7fffe1dd6700 (LWP 12877)):
#0  0x00007ffff1d1b03f in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /usr/lib/libpthread.so.0
#1  0x00007ffff51fd4e7 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff7247976 in ARDOUR::Analyser::work() ()
   from /usr/lib/ardour3/libardour.so.3
#3  0x00007ffff724775f in ?? () from /usr/lib/ardour3/libardour.so.3
#4  0x0000000001485927 in sigc::pointer_functor0<void>::operator()() const ()
#5  0x0000000001482d10 in sigc::adaptor_functor<sigc::pointer_functor0<void> >::operator()() const ()
#6  0x000000000147f7b7 in sigc::internal::slot_call0<sigc::pointer_functor0<void>, void>::call_it(sigc::internal::slot_rep*) ()
#7  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#8  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#9  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#10 0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 4 (Thread 0x7fffe25d7700 (LWP 12876)):
#0  0x00007ffff1d1b03f in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /usr/lib/libpthread.so.0
#1  0x00007ffff51fd4e7 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff766384c in ?? () from /usr/lib/ardour3/libardour.so.3
#3  0x0000000001485927 in sigc::pointer_functor0<void>::operator()() const ()
#4  0x0000000001482d10 in sigc::adaptor_functor<sigc::pointer_functor0<void> >::operator()() const ()
#5  0x000000000147f7b7 in sigc::internal::slot_call0<sigc::pointer_functor0<void>, void>::call_it(sigc::internal::slot_rep*) ()
#6  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#7  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#8  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#9  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 3 (Thread 0x7fffe2dd8700 (LWP 12875)):
#0  0x00007ffff1d1b03f in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /usr/lib/libpthread.so.0
#1  0x00007ffff51fd4e7 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff766384c in ?? () from /usr/lib/ardour3/libardour.so.3
#3  0x0000000001485927 in sigc::pointer_functor0<void>::operator()() const ()
#4  0x0000000001482d10 in sigc::adaptor_functor<sigc::pointer_functor0<void> >::operator()() const ()
#5  0x000000000147f7b7 in sigc::internal::slot_call0<sigc::pointer_functor0<void>, void>::call_it(sigc::internal::slot_rep*) ()
#6  0x00007ffff570aa5d in ?? () from /usr/lib/libglibmm-2.4.so.1
#7  0x00007ffff51e1fb5 in ?? () from /usr/lib/libglib-2.0.so.0
#8  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#9  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 2 (Thread 0x7fffe35d9700 (LWP 12874)):
#0  0x00007ffff0aa9aad in nanosleep () from /usr/lib/libc.so.6
#1  0x00007ffff0ad1c14 in usleep () from /usr/lib/libc.so.6
#2  0x0000000001748a12 in gui_event_loop(void*) ()
#3  0x00007ffff1d170a2 in start_thread () from /usr/lib/libpthread.so.0
#4  0x00007ffff0ad832d in clone () from /usr/lib/libc.so.6

Thread 1 (Thread 0x7ffff7f77940 (LWP 12869)):
#0  0x00007ffff0acf87d in poll () from /usr/lib/libc.so.6
#1  0x00007ffff51bd584 in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff51bd9ea in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#3  0x00007ffff4a669d7 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#4  0x00007ffff6201dea in Gtkmm2ext::UI::run(Receiver&) ()
   from /usr/lib/ardour3/libgtkmm2ext.so.0
#5  0x0000000001297dd5 in main ()
crashtest-gdb-backtrace.txt (17,834 bytes)   

aggraef

2014-02-26 23:04

reporter   ~0015689

Last edited: 2014-02-27 23:12

There's obviously something wrong with the buffer sizes. In Route::fill_buffers_with_input, at route.cc:4184, it tries to copy up to 1024 items (frames? bytes?) from the source into a buffer that only has a capacity of 512. If the source buffer actually has more than 512 items then this obviously trips the assertion that I see.

EDIT: As I found out later, the number 1024 is bogus there, that was just the number of audio frames which is unrelated. The actual MIDI source buffer size there is 2048, see the notes below.

I think that this must be related to Paul's changes in thread_buffers.cc, rev. d1cc7e5. Specifically, line 63 which reads:

  size_t size = _engine->raw_buffer_size (*t) / sizeof (Sample);

I get a value of 512 there. But it ought to be 1024. In fact, if I multiply the above value by 2 then this makes the problem go away. Probably not the right way to fix it, but maybe someone in the know now has an idea what exactly is wrong with that calculation.

aggraef

2014-02-27 21:11

reporter   ~0015691

I should maybe add that I'm running jackd 0.124.1 here, so this should be the latest.

Some figures I determined which might be helpful tracking down the error:

- The Jack backend reports a raw MIDI buffer size of 2048.

- From this, thread_buffers.cc, in ThreadBuffers::ensure_buffers(), calculates a MIDI buffer size of 512 (2048 / 4), so this looks good.

- But route.cc, Route::fill_buffers_with_input(), being called from Track::no_roll() when I stop playback, calls MidiBuffer::copy() on a source buffer whose capacity is 2048 (like the raw MIDI buffer size reported by Jack), not 512. At the time it trips the assertion, the actual size of the source MIDI buffer is 704 which is of course > 512, so that explains the assertion.

I'm not sure where these source buffers come from (still have to dig deeper into the code), but to me it looks like there's still some place in Ardour where it allocates MIDI buffers of capacity 2048, whereas the internal MIDI routing buffers all have a capacity of 512.

aggraef

2014-02-27 21:23

reporter   ~0015692

Also, what's suspicious is that MidiBuffer::copy(const MidiBuffer& copy), in midi_buffer.cc, has the following code:

  memcpy(_data, copy._data, copy._size);

So the assumption there seems to be that the buffer size *is* a raw byte count after all (if this code is correct). So maybe the internal MIDI buffers do need to have a size of 2048 instead of 512?

aggraef

2014-02-27 23:01

reporter   ~0015693

Last edited: 2014-02-27 23:16

Ok, I was able to fix this issue by partially reverting rev. d1cc7e5. I changed thread_buffers.cc:63 so that it reads:

        size_t size = (*t == DataType::MIDI)
          ?_engine->raw_buffer_size (*t)
          :_engine->raw_buffer_size (*t) / sizeof (Sample);

This makes the attached "crashtest" session work, but I then get a different error (Jack zombified) with other, more complicated sessions that I have. This is apparently due to another bug in the MIDI code, at midi_buffer.cc:180 in MidiBuffer::push_back(). Being called (again, when I stop playback) via ARDOUR::Track::no_roll() -> Route::fill_buffers_with_input() -> MidiPort::get_midi_buffer(), there it tries to push back some MIDI events into a buffer, which fails if the buffer is full already. I found that the MIDI events which it tries to "push back" there are all control changes (cc 64 0 on all channels), apparently these are generated by Ardour itself to reset the hold pedal. (Let me know if I should attach the session which demonstrates this bug.)

Anyway, I also changed this code so that it simply prints a warning message instead of doing a stack trace which zombifies Jack. I know that this is only a workaround, the question is why does Ardour generate these pedal controller events in the first place and then tries to push them into to a full MIDI buffer, wreaking havoc along the way?

Suggested patch attached (ardour-midi-bugs.patch). I know that it is not elegant, but it makes things work again for me. Would be nice if someone could review this and commit something along these lines.

TIA,
Albert

2014-02-27 23:01

 

ardour-midi-bugs.patch (1,450 bytes)   
diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc
index 1a6cb7f..b9338c6 100644
--- a/libs/ardour/midi_buffer.cc
+++ b/libs/ardour/midi_buffer.cc
@@ -178,9 +178,17 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
 #endif
 
 	if (_size + stamp_size + size >= _capacity) {
+#if 1
+		fprintf(stderr,
+			"WARNING: MidiBuffer dropping event (buffer full):");
+		for (size_t i=0; i < size; ++i)
+			printf(" 0x%02x", (int)data[i]);
+		printf("\n");
+#else
 		cerr << "MidiBuffer::push_back2 failed (buffer is full; _size = " << _size << " capacity " 
 		     << _capacity << " stamp " << stamp_size << " size = " << size << ")" << endl;
 		PBD::stacktrace (cerr, 20);
+#endif
 		return false;
 	}
 
diff --git a/libs/ardour/thread_buffers.cc b/libs/ardour/thread_buffers.cc
index e469187..a45cb6d 100644
--- a/libs/ardour/thread_buffers.cc
+++ b/libs/ardour/thread_buffers.cc
@@ -60,7 +60,9 @@ ThreadBuffers::ensure_buffers (ChanCount howmany)
 
 	for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 		size_t count = std::max (scratch_buffers->available().get(*t), howmany.get(*t));
-		size_t size = _engine->raw_buffer_size (*t) / sizeof (Sample);
+		size_t size = (*t == DataType::MIDI)
+		  ?_engine->raw_buffer_size (*t)
+		  :_engine->raw_buffer_size (*t) / sizeof (Sample);
 
 		scratch_buffers->ensure_buffers (*t, count, size);
 		mix_buffers->ensure_buffers (*t, count, size);
ardour-midi-bugs.patch (1,450 bytes)   

x42

2014-05-17 20:46

administrator   ~0015788

Hi Albert,

Thanks, I just merged the first part (thread_buffers.cc:63) in 3.5-1967-g205b5d9
https://github.com/Ardour/ardour/commit/205b5d9

as for the libs/ardour/midi_buffer.cc change, that should probably be turned into a one-time PBD::warning with a note to increase jack1's midi-buffer size (-M) option or use jack2 or don't mux too many midi-ports into one.

In any case the root-cause is that ardour send MIDI-panic 3 messages (all notes off, all sound off, reset-controllers) 3 bytes each to every midi-channel when the transport stops. Combined with a small midi-buffer size this could cause overflows. A possible workaround would be to reject duplicate messages (midi-panic) when muxing ports.

Yet with jack2's 32K midi buffer one can mux ( 32768 / 3 [msgs] / 16 [channels] / 3 [bytes per message] ) = 227 midi ports. That's more than any reasonable real-world use-case and the problem should not occur.

If one really needs to mux more ports into one, changing jack's buffersize is the way to go.

Issue History

Date Modified Username Field Change
2014-02-26 22:09 aggraef New Issue
2014-02-26 22:09 aggraef File Added: crashtest.tar.bz2
2014-02-26 22:10 aggraef File Added: crashtest-gdb-backtrace.txt
2014-02-26 23:04 aggraef Note Added: 0015689
2014-02-27 21:11 aggraef Note Added: 0015691
2014-02-27 21:23 aggraef Note Added: 0015692
2014-02-27 23:01 aggraef Note Added: 0015693
2014-02-27 23:01 aggraef File Added: ardour-midi-bugs.patch
2014-02-27 23:09 aggraef Note Edited: 0015693
2014-02-27 23:12 aggraef Note Edited: 0015689
2014-02-27 23:16 aggraef Note Edited: 0015693
2014-05-17 20:46 x42 Note Added: 0015788