C++: terminate called after throwing an instance of

Модератор: Модераторы разделов

IMB
Сообщения: 2513
ОС: Debian

C++: terminate called after throwing an instance of

Сообщение IMB »

Доброго дня!
Реализовал класс исключения наследующий от std::exception

Код: Выделить всё

class change_codec: public std::exception {
    public:
        change_codec(codec_type last,
                    codec_type cur);
        const char *what() const throw() ;
        codec_type last() const;
        codec_type current() const;
    private:
        codec_type _last;
        codec_type _cur;
};

change_codec::change_codec(codec_type last,
                            codec_type cur)
{
    _last = last;
    _cur = cur;
}

const char *change_codec::what() const throw()
{
    std::stringstream m;

    m << "Codec changed from " << _last << " to " << _cur;

    return m.str().c_str();
}

codec_type change_codec::last() const
{
    return _last;
}

codec_type change_codec::current() const
{
    return _cur;
}

Вызов этого исключения:

Код: Выделить всё

if (_codec != _data->codec) {
    sem_post(_sem);
    throw change_codec(_codec, _data->codec);
}

Проверка этого исключения:

Код: Выделить всё

try {
       // основной цикл live555
    env->taskScheduler().doEventLoop(&is_stop);
} catch (change_codec &m) {
    *env << m.what();
}

Я ожидал увидеть сообщение и продолжение или корректную остановку программы, но этого не происходит:

Код: Выделить всё

terminate called after throwing an instance of 'change_codec'
  what():  Codec changed from 4 to 3
Aborted

Вопрос - почему происходит "грубое" завершение программы и как я должен модифицировать класс исключения для решения этой проблемы?
Спасибо.
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: terminate called after throwing an instance of

Сообщение NickLion »

Исключение произошло в другом потоке. Нужно обернуть try-catch в том потоке, где и throw работает.
Спасибо сказали:

IMB
Сообщения: 2513
ОС: Debian

Re: C++: terminate called after throwing an instance of

Сообщение IMB »

Программа однопоточная - берёт данные из источника и создаёт RTP-поток.
Общая схема следующая:
scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
frame = new Frame(env, SEM_NAME); // класс получения данных
rtp = new RTP(env, cfg, MAX_SHARED_SIZE, frame); // класс создания RTP-потока
rtp->start(); // запуск RTP-потока
env->taskScheduler().doEventLoop(&is_stop); // основной цикл запускающий задачи http://www.live555.com/liveMedia/faq.html#control-flow

Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: terminate called after throwing an instance of

Сообщение NickLion »

Тогда чуть больше инфо о программе можно? Пробовали добавлять секции catch(const std::exception&) и catch(...) ?
Спасибо сказали:

IMB
Сообщения: 2513
ОС: Debian

Re: C++: terminate called after throwing an instance of

Сообщение IMB »

Код: Выделить всё

try {
       // основной цикл live555
    env->taskScheduler().doEventLoop(&is_stop);
} catch (change_codec &m) {
    *env << m.what();
} catch (...) {
    *env << "....\n";
}

Поведение не меняется, программа останавливается с тем же сообщением.
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 5105
ОС: Gentoo

Re: C++: terminate called after throwing an instance of

Сообщение /dev/random »

Проверьте через gdb, не генерируется ли это исключение где-то, где вы его не ждали. К примеру, как у вас реализован этот оператор: "*env << ..."? Не может ли он вызвать обработчик событий, который в свою очередь вызвал бы генерирующую исключение функцию?
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: terminate called after throwing an instance of

Сообщение NickLion »

IMB писал(а):
04.12.2013 13:19
rtp = new RTP(env, cfg, MAX_SHARED_SIZE, frame); // класс создания RTP-потока
rtp->start(); // запуск RTP-потока

А что здесь происходит? RTP класса в liveMedia, насколько я помню, нет.

Вообще весь код оберните в try, может исключение происходит не там, где Вы его ловите.
Спасибо сказали:

IMB
Сообщения: 2513
ОС: Debian

Re: C++: terminate called after throwing an instance of

Сообщение IMB »

RTP это класс обёртка над созданием RTP-потока для различных кодеков, в упрощённом виде код такой:

Код: Выделить всё

RTPSink *_sink;
MediaSource *_media;
Groupsock *_sock;
Frame *_frame; // класс наслудеющий от FramedSource

_sock = new Groupsock(*_env, ipv4, Port(cfg->port), cfg->ttl);
_sink = H264VideoRTPSink::createNew(*_env, _sock, 96);
_media = H264VideoStreamDiscreteFramer::createNew(*_env, _frame);
_sink->startPlaying(*_media, NULL, NULL);

Собственно для чего всё этого.
Есть программа, назовём её encoder, захватывающая данные с сенсора и сжимающая их с использованием указанного кодека, кодеков несколько и пользователь может их менять, сжатые данные помещаются в общую память вместе с дополнительной инфомацией, такой как размер данных и используемый кодек, доступ к общей памяти регулируется семафором. Теперь эти данные надо отдать в виде RTP-потока, программа streamer. Что бы проинформировать streamer о необходимости переконфигурировать выходной поток на другой кодек я думаю использовать исключение выбрасываемое классом Frame.
Возможно есть более оптимальный/простой путь, думаю попробовать передавать в класс Frame указатель на callback-функцию, которая и будет переконфигурировать?

/dev/random писал(а):
06.12.2013 14:29
К примеру, как у вас реализован этот оператор: "*env << ..."?

Это оператор live555, я его не изменял, если верить исходникам, то:

Код: Выделить всё

UsageEnvironment/include/UsageEnvironment.hh
// 'console' output:
virtual UsageEnvironment& operator<<(char const* str) = 0;
virtual UsageEnvironment& operator<<(int i) = 0;
virtual UsageEnvironment& operator<<(unsigned u) = 0;
virtual UsageEnvironment& operator<<(double d) = 0;
virtual UsageEnvironment& operator<<(void* p) = 0;
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: terminate called after throwing an instance of

Сообщение NickLion »

Так всё обернуть в try-catch пробовали?
Спасибо сказали:

IMB
Сообщения: 2513
ОС: Debian

Re: C++: terminate called after throwing an instance of

Сообщение IMB »

Простите за задержку, так как наблюдается весьма странная проблема - периодически поток останавливается после отправки первого кадра.
К исключению...

Код: Выделить всё

try {
        rtp = new RTP(env, frame, MAX_SHARED_SIZE, 0, cfg);
        rtp->start();
catch (change_codec &e) {
    daemon_error("%u: %s", __LINE__, e.what());
} catch (...) {
    daemon_error("%u", __LINE__);
}

try {
    env->taskScheduler().doEventLoop(&is_stop);
} catch (change_codec &e) {
    daemon_error("%u: %s", __LINE__, e.what());
} catch (...) {
    daemon_error("%u", __LINE__);
}

Странно, но если верить выводу, то исключение ловится после doEventLoop, собственно где и ожидал, и программа перестала падать, но после появляения исключения поток останавливается, сужу по сетевой активности.
Спасибо сказали: