JvanKatwijk / dab-cmdline

DAB decoding library with example of its use
GNU General Public License v2.0
57 stars 29 forks source link

Segfault on recreating Radio #49

Closed bartpeeters closed 6 years ago

bartpeeters commented 6 years ago

My current usecase requires me to delete the dab radio and device and recreate it:

    theRadio    -> reset ();
    theDevice   -> stopReader ();
    delete theRadio;
    delete theDevice;
    theDevice = NULL;
    theRadio = NULL;

Then after a user action recreate device and radio:

  try {
#ifdef  HAVE_SDRPLAY
     theDevice  = new sdrplayHandler (frequency,
                                        ppmCorrection,
                                        theGain,
                                        autogain,
                                        0,
                                        0);
#endif

  }
  catch (int e) {
     std::cerr << "allocating device failed (" << e << "), fatal\n";
     exit (32);
  }

  if (soundOut == NULL) {   // not bound to a file?
     soundOut   = new audioSink (latency, soundChannel, &err);
     if (err) {
        std::cerr << "no valid sound channel, fatal\n";
        exit (33);
     }
  }

  //
  //    and with a sound device we now can create a "backend"
    theRadio    = new dabClass (theDevice,
                                    theMode,
                                    NULL,       // no spectrum shown
                                    NULL,       // no constellations
                                    syncsignalHandler,
                                    systemData,
                                    ensemblenameHandler,
                                    programnameHandler,
                                    fibQuality,
                                    pcmHandler,
                                    dataOut_Handler,
                                    bytesOut_Handler,
                                    programdataHandler,
                                    mscQuality,
                                    motdataHandler, // MOT in PAD
                                    NULL        // Ctx
                                   );
    if (theRadio == NULL) {
       std::cerr << "sorry, no radio available, fatal\n";
       exit (4);
    }

    theDevice   -> setGain (theGain);
    if (autogain)
       theDevice    -> set_autogain (autogain);
    theDevice   -> setVFOFrequency (frequency);
    theDevice   -> restartReader ();
    theDevice   -> setGain (theGain);
    if (autogain)
       theDevice    -> set_autogain (autogain);
    theDevice   -> setVFOFrequency (frequency);
  //
  //    The device should be working right now

    theRadio -> startProcessing ();

This sometimes gives me the following segfault:

#0  0x00007ffff6159a43 in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6
#1  0x000055555588cbe2 in mscHandler::process_mscBlock (this=0x7fffe4005f20, b=0x8001fa649fc0, blkno=1) at /home/bart/Projects/dab-cmdline/library/src/backend/msc-handler.cpp:123
#2  0x000055555587e527 in dabProcessor::run (this=0x7fffe4001400) at /home/bart/Projects/dab-cmdline/library/src/dab-processor.cpp:218
#3  0x000055555587f456 in std::__invoke_impl<void, void (dabProcessor::*)(), dabProcessor*> (__f=@0x7fffe40061e0: &virtual dabProcessor::run(), __t=@0x7fffe40061d8: 0x7fffe4001400)
    at /usr/include/c++/8.2.0/bits/invoke.h:73
#4  0x000055555587ec2a in std::__invoke<void (dabProcessor::*)(), dabProcessor*> (__fn=@0x7fffe40061e0: &virtual dabProcessor::run(), __args#0=@0x7fffe40061d8: 0x7fffe4001400)
    at /usr/include/c++/8.2.0/bits/invoke.h:95
#5  0x000055555588047d in std::thread::_Invoker<std::tuple<void (dabProcessor::*)(), dabProcessor*> >::_M_invoke<0ul, 1ul> (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:234
#6  0x0000555555880423 in std::thread::_Invoker<std::tuple<void (dabProcessor::*)(), dabProcessor*> >::operator() (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:243
#7  0x00005555558803f8 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (dabProcessor::*)(), dabProcessor*> > >::_M_run (this=0x7fffe40061d0)
    at /usr/include/c++/8.2.0/thread:186
#8  0x00007ffff6419043 in execute_native_thread_routine () at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:80
#9  0x00007ffff73a5a8d in start_thread () from /usr/lib/libpthread.so.0
#10 0x00007ffff60f5823 in clone () from /usr/lib/libc.so.6

Any idea what might cause this or how should I cleanly delete and recreate the device and radio?

JvanKatwijk commented 6 years ago

Last week I threw out the dabClass, at the time it was a quick hack, but it had limitations. Note that the library was - originally - not meant to be used with dynamic channel selection, but it might work

From example 6 I take the following code that works as example fprintf (stderr, "channel request\n"); dabStop (theRadio); theDevice -> stopReader (); fprintf (stderr, "radio and device stopped\n"); my_radioData. theChannel = std::string ((char )(&(lbuf [3]))); fprintf (stderr, "selecting channel %s\n", (char )(&(buffer [1]))); { int frequency = theBandHandler -> Frequency (my_radioData. theBand, my_radioData. theChannel); theDevice -> setVFOFrequency (frequency); } dabStartProcessing (theRadio); theDevice -> restartReader (); programNames. resize (0); programSIds . resize (0); break;

I rewrote the examples to use the dab-api rather than dabClass, much more flexibility and - yes - a little more work Initalize by calling dabInit with a lot of parameters void *theRadio; theRadio

2018-08-12 20:29 GMT+02:00 Bart Peeters notifications@github.com:

My current usecase requires me to delete the dab radio and device and recreate it:

theRadio  -> reset ();
theDevice -> stopReader ();
delete theRadio;
delete theDevice;
theDevice = NULL;
theRadio = NULL;

Then after a user action recreate device and radio:

try {

ifdef HAVE_SDRPLAY

 theDevice    = new sdrplayHandler (frequency,
                                    ppmCorrection,
                                    theGain,
                                    autogain,
                                    0,
                                    0);

endif

} catch (int e) { std::cerr << "allocating device failed (" << e << "), fatal\n"; exit (32); }

if (soundOut == NULL) { // not bound to a file? soundOut = new audioSink (latency, soundChannel, &err); if (err) { std::cerr << "no valid sound channel, fatal\n"; exit (33); } }

// // and with a sound device we now can create a "backend" theRadio = new dabClass (theDevice, theMode, NULL, // no spectrum shown NULL, // no constellations syncsignalHandler, systemData, ensemblenameHandler, programnameHandler, fibQuality, pcmHandler, dataOut_Handler, bytesOut_Handler, programdataHandler, mscQuality, motdataHandler, // MOT in PAD NULL // Ctx ); if (theRadio == NULL) { std::cerr << "sorry, no radio available, fatal\n"; exit (4); }

theDevice -> setGain (theGain);
if (autogain)
   theDevice  -> set_autogain (autogain);
theDevice -> setVFOFrequency (frequency);
theDevice -> restartReader ();
theDevice -> setGain (theGain);
if (autogain)
   theDevice  -> set_autogain (autogain);
theDevice -> setVFOFrequency (frequency);

// // The device should be working right now

theRadio -> startProcessing ();

This sometimes gives me the following segfault:

0 0x00007ffff6159a43 in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6

1 0x000055555588cbe2 in mscHandler::process_mscBlock (this=0x7fffe4005f20, b=0x8001fa649fc0, blkno=1) at /home/bart/Projects/dab-cmdline/library/src/backend/msc-handler.cpp:123

2 0x000055555587e527 in dabProcessor::run (this=0x7fffe4001400) at /home/bart/Projects/dab-cmdline/library/src/dab-processor.cpp:218

3 0x000055555587f456 in std::__invoke_impl<void, void (dabProcessor::)(), dabProcessor> (f=@0x7fffe40061e0: &virtual dabProcessor::run(), t=@0x7fffe40061d8: 0x7fffe4001400)

at /usr/include/c++/8.2.0/bits/invoke.h:73

4 0x000055555587ec2a in std::invoke<void (dabProcessor::)(), dabProcessor> (fn=@0x7fffe40061e0: &virtual dabProcessor::run(), __args#0=@0x7fffe40061d8: 0x7fffe4001400)

at /usr/include/c++/8.2.0/bits/invoke.h:95

5 0x000055555588047d in std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> >::_M_invoke<0ul, 1ul> (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:234

6 0x0000555555880423 in std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> >::operator() (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:243

7 0x00005555558803f8 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> > >::_M_run (this=0x7fffe40061d0)

at /usr/include/c++/8.2.0/thread:186

8 0x00007ffff6419043 in execute_native_thread_routine () at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:80

9 0x00007ffff73a5a8d in start_thread () from /usr/lib/libpthread.so.0

10 0x00007ffff60f5823 in clone () from /usr/lib/libc.so.6

Any idea what might cause this or how should I cleanly delete and recreate the device and radio?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JvanKatwijk/dab-cmdline/issues/49, or mute the thread https://github.com/notifications/unsubscribe-auth/AITzwCCvfMd9gJtK6ZfQ340rH5qPRtAqks5uQHQKgaJpZM4V5o2Q .

-- Jan van Katwijk

+31 (0)15 3698980 +31 (0) 628260355

JvanKatwijk commented 6 years ago

sorry, wrong key

I rewrote the examples to use the dab-api rather than dabClass, much more flexibility and - yes - a little more work Initalize by calling dabInit with a lot of parameters void *theRadio; theRadio = dabInit (.....) dabStartprocessing (theRadio) will start the threads in the library dabStop (theRadio) will stop

          is_audioService (theRadio, "name") will test whether or not a

service "name" exists with audio, is_dataService (theRadio, "name") does the same for data services

         another fragment shows how it is used in example 6

         if (is_audioService (theRadio,
                                  my_radioData. serviceName. c_str ()))

{ audiodata ad; dataforAudioService (theRadio, my_radioData. serviceName. c_str (), &ad, 0); if (!ad. defined) { std::cerr << "sorry we cannot handle service " << my_radioData. serviceName << "\n"; running. store (false); } else { dabReset_msc (theRadio); set_audioChannel (theRadio, &ad); } } break;

dataforAudioService fills a struct with the relevant data to decode an audiostream Since there is as such no limit in the number of open streams, it is wise to use dabReset_msc before starting a new stream, that will terminate all exisiting stream handlers

example 6 is working an shows - in a limited way - how to handle the library with a remote control

best jan

2018-08-13 13:47 GMT+02:00 jan van katwijk j.vankatwijk@gmail.com:

Last week I threw out the dabClass, at the time it was a quick hack, but it had limitations. Note that the library was - originally - not meant to be used with dynamic channel selection, but it might work

From example 6 I take the following code that works as example fprintf (stderr, "channel request\n"); dabStop (theRadio); theDevice -> stopReader (); fprintf (stderr, "radio and device stopped\n"); my_radioData. theChannel = std::string ((char )(&(lbuf [3]))); fprintf (stderr, "selecting channel %s\n", (char )(&(buffer [1]))); { int frequency = theBandHandler -> Frequency (my_radioData. theBand, my_radioData. theChannel); theDevice -> setVFOFrequency (frequency); } dabStartProcessing (theRadio); theDevice -> restartReader (); programNames. resize (0); programSIds . resize (0); break;

I rewrote the examples to use the dab-api rather than dabClass, much more flexibility and - yes - a little more work Initalize by calling dabInit with a lot of parameters void *theRadio; theRadio

2018-08-12 20:29 GMT+02:00 Bart Peeters notifications@github.com:

My current usecase requires me to delete the dab radio and device and recreate it:

theRadio -> reset ();
theDevice    -> stopReader ();
delete theRadio;
delete theDevice;
theDevice = NULL;
theRadio = NULL;

Then after a user action recreate device and radio:

try {

ifdef HAVE_SDRPLAY

 theDevice   = new sdrplayHandler (frequency,
                                    ppmCorrection,
                                    theGain,
                                    autogain,
                                    0,
                                    0);

endif

} catch (int e) { std::cerr << "allocating device failed (" << e << "), fatal\n"; exit (32); }

if (soundOut == NULL) { // not bound to a file? soundOut = new audioSink (latency, soundChannel, &err); if (err) { std::cerr << "no valid sound channel, fatal\n"; exit (33); } }

// // and with a sound device we now can create a "backend" theRadio = new dabClass (theDevice, theMode, NULL, // no spectrum shown NULL, // no constellations syncsignalHandler, systemData, ensemblenameHandler, programnameHandler, fibQuality, pcmHandler, dataOut_Handler, bytesOut_Handler, programdataHandler, mscQuality, motdataHandler, // MOT in PAD NULL // Ctx ); if (theRadio == NULL) { std::cerr << "sorry, no radio available, fatal\n"; exit (4); }

theDevice    -> setGain (theGain);
if (autogain)
   theDevice -> set_autogain (autogain);
theDevice    -> setVFOFrequency (frequency);
theDevice    -> restartReader ();
theDevice    -> setGain (theGain);
if (autogain)
   theDevice -> set_autogain (autogain);
theDevice    -> setVFOFrequency (frequency);

// // The device should be working right now

theRadio -> startProcessing ();

This sometimes gives me the following segfault:

0 0x00007ffff6159a43 in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6

1 0x000055555588cbe2 in mscHandler::process_mscBlock (this=0x7fffe4005f20, b=0x8001fa649fc0, blkno=1) at /home/bart/Projects/dab-cmdline/library/src/backend/msc-handler.cpp:123

2 0x000055555587e527 in dabProcessor::run (this=0x7fffe4001400) at /home/bart/Projects/dab-cmdline/library/src/dab-processor.cpp:218

3 0x000055555587f456 in std::__invoke_impl<void, void (dabProcessor::)(), dabProcessor> (f=@0x7fffe40061e0: &virtual dabProcessor::run(), t=@0x7fffe40061d8: 0x7fffe4001400)

at /usr/include/c++/8.2.0/bits/invoke.h:73

4 0x000055555587ec2a in std::invoke<void (dabProcessor::)(), dabProcessor> (fn=@0x7fffe40061e0: &virtual dabProcessor::run(), __args#0=@0x7fffe40061d8: 0x7fffe4001400)

at /usr/include/c++/8.2.0/bits/invoke.h:95

5 0x000055555588047d in std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> >::_M_invoke<0ul, 1ul> (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:234

6 0x0000555555880423 in std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> >::operator() (this=0x7fffe40061d8) at /usr/include/c++/8.2.0/thread:243

7 0x00005555558803f8 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (dabProcessor::)(), dabProcessor> > >::_M_run (this=0x7fffe40061d0)

at /usr/include/c++/8.2.0/thread:186

8 0x00007ffff6419043 in execute_native_thread_routine () at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:80

9 0x00007ffff73a5a8d in start_thread () from /usr/lib/libpthread.so.0

10 0x00007ffff60f5823 in clone () from /usr/lib/libc.so.6

Any idea what might cause this or how should I cleanly delete and recreate the device and radio?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JvanKatwijk/dab-cmdline/issues/49, or mute the thread https://github.com/notifications/unsubscribe-auth/AITzwCCvfMd9gJtK6ZfQ340rH5qPRtAqks5uQHQKgaJpZM4V5o2Q .

-- Jan van Katwijk

+31 (0)15 3698980 +31 (0) 628260355

-- Jan van Katwijk

+31 (0)15 3698980 +31 (0) 628260355

bartpeeters commented 6 years ago

Hey Jan,

I reworked the program to use the dab-api and example-6, it works, but for my usecase I need to recreate the device: when the radio is stopped the power to the RTLSDR stick is also cut off, because it doesn't seem to stop draining power and gets hot, but if I then restartReader on the device I get the following:

rtlsdr_write_reg failed with -4
rtlsdr_write_reg failed with -4
rtlsdr_demod_write_reg failed with -4
starting mscHandler
Failed to submit transfer 0!
rtlsdr_demod_read_reg failed with -4
r82xx_write: i2c wr failed=-4 reg=05 len=1
rtlsdr_demod_write_reg failed with -4
rtlsdr_demod_read_reg failed with -4
rtlsdr_demod_write_reg failed with -4
rtlsdr_demod_read_reg failed with -4

And my quick and dirty solution was to just recreate theDevice, and the radio but that gives the Segmentation fault.

JvanKatwijk commented 6 years ago

If you close the device, then it has to be reopened again, i.e. a new "setup" (i.e. "delete device; device = new sdrplayHandler (...)). Of course it can be done but it requires a move of the "new sdrplayHandler" code to a different place

2018-08-13 20:07 GMT+02:00 Bart Peeters notifications@github.com:

Hey Jan,

I reworked the program to use the dab-api and example-6, it works, but for my usecase I need to recreate the device: when the radio is stopped the power to the RTLSDR stick is also cut off, because it doesn't seem to stop draining power and gets hot, but if I then restartReader on the device I get the following:

rtlsdr_write_reg failed with -4 rtlsdr_write_reg failed with -4 rtlsdr_demod_write_reg failed with -4 starting mscHandler Failed to submit transfer 0! rtlsdr_demod_read_reg failed with -4 r82xx_write: i2c wr failed=-4 reg=05 len=1 rtlsdr_demod_write_reg failed with -4 rtlsdr_demod_read_reg failed with -4 rtlsdr_demod_write_reg failed with -4 rtlsdr_demod_read_reg failed with -4

And my quick and dirty solution was to just recreate theDevice, and the radio but that gives the Segmentation fault.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/JvanKatwijk/dab-cmdline/issues/49#issuecomment-412611092, or mute the thread https://github.com/notifications/unsubscribe-auth/AITzwA2JM1JWMNG5Wp-RYPOYjb34zUUNks5uQcBHgaJpZM4V5o2Q .

-- Jan van Katwijk

+31 (0)15 3698980 +31 (0) 628260355

bartpeeters commented 6 years ago

Issue fixed by pull request: https://github.com/JvanKatwijk/dab-cmdline/pull/50

I think this was the problem: First creation of the radio was done using clean memory so the T_g was 0, then after deleting the radio and recreating it T_g was some garbage memory != 0 which gave the segfault later on in the mscHandler.

JvanKatwijk commented 6 years ago

It was a pretty stupid error actually and should not have happened

Op zo 19 aug. 2018 om 12:06 schreef Bart Peeters notifications@github.com:

Issue fixed by pull request: #50 https://github.com/JvanKatwijk/dab-cmdline/pull/50

I think this was the problem: First creation of the radio was done using clean memory so the T_g was 0, then after deleting the radio and recreating it T_g was some garbage memory != 0 which gave the segfault later on in the mscHandler.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/JvanKatwijk/dab-cmdline/issues/49#issuecomment-414117179, or mute the thread https://github.com/notifications/unsubscribe-auth/AITzwDLyXV_hKjNXWUD4HS8bMjGQeakkks5uSTiWgaJpZM4V5o2Q .

-- Jan van Katwijk

+31 (0)15 3698980 +31 (0) 628260355