I'm having a problem with the Polyphase Clock Sync block.  I believe what's
happening is that the block is calling get_tags_in_range improperly and
then causing an infiite loop in gnuradio-runtime/lib/buffer.cc, at this
point the PFB Clock Sync block stops emitting samples.

The problem occurs in the PFB clock sync block here:
https://github.com/gnuradio/gnuradio/blob/master/gr-digital/lib/pfb_clock_sync_ccf_impl.cc#L473

The PFB block calls get_tags_in_range where the start sample number is
greater than then end sample number, here's the code in buffer.cc that may
be getting stuck in an infiite loop.

The entire file is here:
https://github.com/gnuradio/gnuradio/blob/master/gnuradio-runtime/lib/buffer.cc#L354

  void
  buffer_reader::get_tags_in_range(std::vector<tag_t> &v,
                                   uint64_t abs_start,
                                   uint64_t abs_end,
                                   long id)
  {
    gr::thread::scoped_lock guard(*mutex());

    v.resize(0);
    std::multimap<uint64_t,tag_t>::iterator itr =
d_buffer->get_tags_lower_bound(std::min(abs_start, abs_start -
d_attr_delay));
    std::multimap<uint64_t,tag_t>::iterator itr_end =
d_buffer->get_tags_upper_bound(std::min(abs_end, abs_end -
d_attr_delay));

    uint64_t item_time;
    while(itr != itr_end) {
      item_time = (*itr).second.offset + d_attr_delay;
      if((item_time >= abs_start) && (item_time < abs_end)) {
        std::vector<long>::iterator id_itr;
        id_itr = std::find(itr->second.marked_deleted.begin(),
itr->second.marked_deleted.end(), id);
        // If id is not in the vector of marked blocks
        if(id_itr == itr->second.marked_deleted.end()) {
          tag_t t = (*itr).second;
          t.offset += d_attr_delay;
          v.push_back(t);
          v.back().marked_deleted.clear();
        }
      }
      itr++;
    }
  }

When I run into this problem, my code seems to get stuck on itr++ (see
debugger output below).  Though I'm not sure if the itr++ call just stalls
or if itr just never equals itr_end.

When the PFB Clock Sync block stalls, I attach with GDB, find the PFB
thread and get a back trace, I then go to the PFB general_work frame and
print the two inputs to get_tags_in_range

(gdb) bt
#0  0x00007f4505db7b30 in local_Rb_tree_increment (__x=0x7f43a801ab90) at
../../../../../src/libstdc++-v3/src/c++98/tree.cc:71
#1  std::_Rb_tree_increment (__x=0x7f43a801ab90) at
../../../../../src/libstdc++-v3/src/c++98/tree.cc:85
#2  0x00007f450678ed27 in std::_Rb_tree_iterator<std::pair<unsigned long
const, gr::tag_t> >::operator++ (this=0x7f43baffc570)
    at /usr/include/c++/4.8/bits/stl_tree.h:197
#3  0x00007f450678e075 in gr::buffer_reader::get_tags_in_range
(this=0x3050350, v=..., abs_start=2833152, abs_end=2833150, id=81)
    at /root/gnuradio/gnuradio-runtime/lib/buffer.cc:367
#4  0x00007f4506778c79 in gr::block_detail::get_tags_in_range
(this=0x3211be0, v=..., which_input=0, abs_start=2833152, abs_end=2833150,
    id=81) at /root/gnuradio/gnuradio-runtime/lib/block_detail.cc:224
#5  0x00007f450676ef92 in gr::block::get_tags_in_range (this=0x30a6800,
v=..., which_input=0, start=2833152, end=2833150)
    at /root/gnuradio/gnuradio-runtime/lib/block.cc:252
#6  0x00007f44f6bc200c in
gr::digital::pfb_clock_sync_ccf_impl::general_work (this=0x30a6710,
noutput_items=128, ninput_items=...,
    input_items=..., output_items=...) at
/root/gnuradio/gr-digital/lib/pfb_clock_sync_ccf_impl.cc:473
#7  0x00007f450677fe03 in gr::block_executor::run_one_iteration
(this=0x7f43baffcd20)
    at /root/gnuradio/gnuradio-runtime/lib/block_executor.cc:451
#8  0x00007f45067d5ffc in gr::tpb_thread_body::tpb_thread_body
(this=0x7f43baffcd20, block=..., max_noutput_items=8192)
    at /root/gnuradio/gnuradio-runtime/lib/tpb_thread_body.cc:122
#9  0x00007f45067c6df1 in gr::tpb_container::operator() (this=0x317c870) at
/root/gnuradio/gnuradio-runtime/lib/scheduler_tpb.cc:44
#10 0x00007f45067c7406 in
gr::thread::thread_body_wrapper<gr::tpb_container>::operator()
(this=0x317c870)
    at
/root/gnuradio/gnuradio-runtime/include/gnuradio/thread/thread_body_wrapper.h:51
#11 0x00007f45067c72d9 in
boost::detail::function::void_function_obj_invoker0<gr::thread::thread_body_wrapper<gr::tpb_container>,
void>::invoke (function_obj_ptr=...) at
/usr/include/boost/function/function_template.hpp:153
#12 0x00007f450675aa36 in boost::function0<void>::operator()
(this=0x32257b8) at /usr/include/boost/function/function_template.hpp:767
#13 0x00007f450675a9e2 in boost::detail::thread_data<boost::function0<void>
>::run (this=0x3225600)
    at /usr/include/boost/thread/detail/thread.hpp:117
#14 0x00007f450544ee7a in ?? () from
/usr/lib/x86_64-linux-gnu/libboost_thread.so.1.55.0
#15 0x00007f4508a03184 in start_thread () from
/lib/x86_64-linux-gnu/libpthread.so.0
#16 0x00007f450873037d in clone () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) f 6
#6  0x00007f44f6bc200c in
gr::digital::pfb_clock_sync_ccf_impl::general_work (this=0x30a6710,
noutput_items=128, ninput_items=...,
    input_items=..., output_items=...) at
/root/gnuradio/gr-digital/lib/pfb_clock_sync_ccf_impl.cc:473
473               get_tags_in_range(xtags, 0, d_old_in, d_new_in);
(gdb) list
468
469               // Manage Tags
470               std::vector<tag_t> xtags;
471               std::vector<tag_t>::iterator itags;
472               d_new_in = nitems_read(0) + count + d_out_idx + d_sps;
473               get_tags_in_range(xtags, 0, d_old_in, d_new_in);
474               for(itags = xtags.begin(); itags != xtags.end(); itags++)
{
475                 tag_t new_tag = *itags;
476                 //new_tag.offset = d_last_out +
d_taps_per_filter/(2*d_sps) - 2;
477                 new_tag.offset = d_last_out + d_taps_per_filter/4 - 2;
(gdb) print d_new_in
$19 = 2833150
(gdb) print d_old_in
$20 = 2833152
(gdb) f 3
#3  0x00007f450678e075 in gr::buffer_reader::get_tags_in_range
(this=0x3050350, v=..., abs_start=2833152, abs_end=2833150, id=81)
    at /root/gnuradio/gnuradio-runtime/lib/buffer.cc:367
367           itr++;
(gdb) list
362               t.offset += d_attr_delay;
363               v.push_back(t);
364               v.back().marked_deleted.clear();
365             }
366           }
367           itr++;
368         }
369       }
370
371       long
(gdb) print itr
$21 = {_M_node = 0x7f43a801ab90}
(gdb) print itr++
$22 = {_M_node = 0x7f43a801ab90}
(gdb) print (itr++)++
Attempt to take address of value not located in memory.
(gdb) print (itr+1)
No symbol "operator+" in current context.
(gdb) print (*itr+1)
No symbol "operator+" in current context.
(gdb) print *itr
$23 = (std::pair<unsigned long const, gr::tag_t> &) @0x7f43a801abb0: {first
= 2833501, second = {offset = 2833501, key = {
      px = 0x7f4344000950}, value = {px = 0x7f43a801ab70}, srcid = {px =
0x2ec72d0},
    marked_deleted = {<std::_Vector_base<long, std::allocator<long> >> = {
        _M_impl = {<std::allocator<long>> =
{<__gnu_cxx::new_allocator<long>> = {<No data fields>}, <No data fields>},
_M_start = 0x0,
          _M_finish = 0x0, _M_end_of_storage = 0x0}}, <No data fields>}}}

I've also found (separately, using breakpoints) that sometimes count is
negative.  Is that the way it should be?

(gdb) print nitems_read(0)
$10 = 711771
(gdb) print count
$11 = -1
(gdb) print d_sps
$12 = 2
(gdb) print d_out_idx
$13 = 0
(gdb) print d_new_in
$14 = 711772
(gdb) print d_old_in
$15 = 711771

I'm not sure if we're putting bad data into the PFB block or if there's
some bug in the PFB block.  Or should there be some checking in
get_tags_in_range that checks if start > end.  What's the best way to
proceed?

Thanks,
Devin
_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to