Проблемы с boost::coroutine
От: chaotic-good  
Дата: 27.01.15 10:16
Оценка: -1
Добрый день.
У меня возникла следующая проблема. Есть сопрограмма, внутри этой сопрограммы выбрасывается исключение, оно успешно разворачивает стек и покидает сопрограмму, после чего ловится в вызывавшем сопрограмму коде. Исключение кидается с помощью BOOST_THROW_EXCEPTION. Проблема в том, что в тестах это исключение не ловится. Я написал тесты с помощью boost test и вот там исключение не ловится вообще. В основном приложении все равботает, в тестах — нет, как такое может быть? Может boost test что-то делать, чтобы перехватывать исключения?
Re: Проблемы с boost::coroutine
От: Abyx Россия  
Дата: 27.01.15 10:34
Оценка:
Здравствуйте, chaotic-good, Вы писали:

пост отредактирован модератором
короткий самодостаточный пример?
In Zen We Trust
Отредактировано 27.01.2015 22:09 Кодт . Предыдущая версия .
Re[2]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 27.01.15 11:11
Оценка:
A>SSCCE или GTFO.

это невозможно по ряду причин, воспроизводится не везде, требует сложной сборки двух бинарников, в общем, я к опыту взываю, может кто просто сталкивался с подобным уже
Re[3]: Проблемы с boost::coroutine
От: jazzer Россия Skype: enerjazzer
Дата: 27.01.15 12:03
Оценка:
Здравствуйте, chaotic-good, Вы писали:

A>>SSCCE или GTFO.


CG>это невозможно по ряду причин, воспроизводится не везде, требует сложной сборки двух бинарников, в общем, я к опыту взываю, может кто просто сталкивался с подобным уже


пальцем в небо — исключение пересекает границу so? У меня такая радость с gcc безо всяких корутин — исключение из so в главной проге не всегда ловится (с gcc3 проблем не было, началось с gcc4).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Проблемы с boost::coroutine
От: Vain Россия google.ru
Дата: 27.01.15 21:57
Оценка:
Здравствуйте, chaotic-good, Вы писали:

CG>Добрый день.

CG>У меня возникла следующая проблема. Есть сопрограмма, внутри этой сопрограммы выбрасывается исключение, оно успешно разворачивает стек и покидает сопрограмму, после чего ловится в вызывавшем сопрограмму коде. Исключение кидается с помощью BOOST_THROW_EXCEPTION. Проблема в том, что в тестах это исключение не ловится. Я написал тесты с помощью boost test и вот там исключение не ловится вообще. В основном приложении все равботает, в тестах — нет, как такое может быть? Может boost test что-то делать, чтобы перехватывать исключения?
а кидаемые исключения от std::exception наследованы?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Проблемы с boost::coroutine
От: smeeld  
Дата: 27.01.15 23:53
Оценка: :)
Здравствуйте, chaotic-good, Вы писали:

CG>Добрый день.

CG>У меня возникла следующая проблема. Есть сопрограмма, внутри этой сопрограммы выбрасывается исключение, оно успешно разворачивает стек и покидает сопрограмму, после чего ловится в вызывавшем сопрограмму коде. Исключение кидается с помощью BOOST_THROW_EXCEPTION. Проблема в том, что в тестах это исключение не ловится. Я написал тесты с помощью boost test и вот там исключение не ловится вообще. В основном приложении все равботает, в тестах — нет, как такое может быть? Может boost test что-то делать, чтобы перехватывать исключения?

Воообще странно, но вообще, кидать исключения в короутинах, оно наверно неправильно,
так как исключение обрабатывается дважды, для pull_type, например, сначала в исполнении калбека fn_:

try
  typename PushCoro::synth_type b( & this->callee, & this->caller, false, base_t::preserve_fpu() );
        PushCoro push_coro( synthesized_t::syntesized, b);
        try
        { fn_( push_coro); }
        catch ( forced_unwind const&)
        {}
        catch (...)
        { base_t::except_ = current_exception(); }

        base_t::flags_ |= flag_complete;
        base_t::flags_ &= ~flag_running;
        typename base_t::param_type to;
        this->callee.jump(
            this->caller,                       /* <<<<<<<<<<<<<<Возврат в caller */
            reinterpret_cast< intptr_t >( & to),
            base_t::preserve_fpu() );


После в контексте caller-а так:
 param_type * from(
            reinterpret_cast< param_type * >(
                caller_->jump(
                    * callee_,
                    reinterpret_cast< intptr_t >( & to),   /* <<<<<<<<<<<<<<<< Уход в контекст callee */
                    preserve_fpu() ) ) );
        flags_ &= ~flag_running;
        if ( from->do_unwind) throw forced_unwind();
        if ( except_) rethrow_exception( except_);  /*  <<<<<<<<<<<<<<<< После возврата из callee повторное кидалово */
    }


Оно надо? Что до исключений, то тут искать нужно не в boost coroutine, а в этих boost test, который может
опции компилятора какие ставит, при которых исключения вообще отключаются или какого ещё хлама они там напридумывали.

ЗЫ boost-это мусорное ведро, если кто не в курсе.
Re: Проблемы с boost::coroutine
От: landerhigh Пират  
Дата: 28.01.15 01:18
Оценка:
Здравствуйте, chaotic-good, Вы писали:

CG>Добрый день.

CG>У меня возникла следующая проблема. Есть сопрограмма, внутри этой сопрограммы выбрасывается исключение, оно успешно разворачивает стек и покидает сопрограмму, после чего ловится в вызывавшем сопрограмму коде.

Вот это звучит очень подозрительно. Единственный правильный способ "покинуть" корутину — это прыгнуть обратно в вызывающий контекст. Соответственно, в корутине исключение должно быть поймано, контекст переключен и уже после переключения вызывающий контекст должен сам проверить, а был ли мальчик, то есть исключение.
Вообще, идея кидать исключения внтури корутин, а обрабатывать их в другом контексте, имхо, чаще всего несколько неправильная.
www.blinnov.com
Re[2]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 06:47
Оценка:
S>Воообще странно, но вообще, кидать исключения в короутинах, оно наверно неправильно,
S>так как исключение обрабатывается дважды
S>Оно надо?

Оно надо, ибо корутина — долгоживущая. Это часть сервера реализующая парсер протокола. В сокет прилетают данные не точно побитые на фреймы, они передаются в корутину и она парсит столько, сколько возможно, а потом возвращает управление если данных не хватает, потом получает новый буфер и продолжает парсить ну и тд. Вот как из этого всего вернуть ошибку правильнее всего, если не с помощью исключения?

S>ЗЫ boost-это мусорное ведро, если кто не в курсе.


За неимением альтернатив приходится использовать буст. В APR и glib не реализованы корутины и кое что еще, ну и asio мне нравится.
Re[2]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 06:48
Оценка:
L>Вообще, идея кидать исключения внтури корутин, а обрабатывать их в другом контексте, имхо, чаще всего несколько неправильная.

Это один из юзкейсов корутин, описанный в документации.
Re: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 06:50
Оценка:
CG>У меня возникла следующая проблема. Есть сопрограмма, внутри этой сопрограммы выбрасывается исключение, оно успешно разворачивает стек и покидает сопрограмму, после чего ловится в вызывавшем сопрограмму коде. Исключение кидается с помощью BOOST_THROW_EXCEPTION. Проблема в том, что в тестах это исключение не ловится. Я написал тесты с помощью boost test и вот там исключение не ловится вообще. В основном приложении все равботает, в тестах — нет, как такое может быть? Может boost test что-то делать, чтобы перехватывать исключения?

проблема оказалась очень тупой, исключение выбрасывалось как надо, не проглатывалось, просто gdb тупил и брейкпоинт не срабатывал в обработчике исключения почему-то, сам обработчик при этом отрабатывал (это обнаружилось тупым отладочным выводом)
Re[3]: Проблемы с boost::coroutine
От: landerhigh Пират  
Дата: 28.01.15 11:42
Оценка: 7 (1)
Здравствуйте, chaotic-good, Вы писали:

L>>Вообще, идея кидать исключения внтури корутин, а обрабатывать их в другом контексте, имхо, чаще всего несколько неправильная.


CG>Это один из юзкейсов корутин, описанный в документации.


Мне хитрая рыжая морда этого юзкейса очень не нравится.

Мой продукт, уже давно в продакшене на куче сайтов — тоже сетевой клиент. Сделан на первой версии boost::context, еще до того, как boost::coroutine официально оформилась. Я тоже смотрел на current_exception, но решил, что нуегонафиг.

Перевыброс исключения в другом контексте мне не нравится по двум причинам:
1. Теряешь оригинальный стек. Его, конечно, можно восстановить, но придется будить внутреннего мыщъх'а. Короче, удачной отладки крешдампа!
2. Размазываешь обработку ошибок почем зря

Последний тезис хочу развернуть. Вся суть использования корутин заключаетя в том, что ты пишешь асинхронный код в синхронном виде. Как-то вот так:


while (connection.up())
{
    try
    {
        yield sendRequest();
        ParseRequest();
        ProcessRequest();
    }
    catch (const TCPConnectionException& Ex)
    {
        // connection lost, close socket and return from coroutine
    }
    catch (const ParseException& Ex)
    {
        // either re-try, skip, or close the connection and return from coroutine
    }
}



То есть весь процесс спрятан внутри корутины, и единственный случай, когда происходит выход из нее — когда соединение закрыто. При этом все ошибки, связанные собственно с тем, что творилось в этом соединении, обрабатываются локально и не выпускаются наружу.
Попытка выпустить исключение для обработки в вызываемом контексте ИМХО убивает все преимущества использования корути на корню и запутывает код.
www.blinnov.com
Re[4]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 13:08
Оценка:
L>Мне хитрая рыжая морда этого юзкейса очень не нравится.

L>Мой продукт, уже давно в продакшене на куче сайтов — тоже сетевой клиент. Сделан на первой версии boost::context, еще до того, как boost::coroutine официально оформилась. Я тоже смотрел на current_exception, но решил, что нуегонафиг.


L>Перевыброс исключения в другом контексте мне не нравится по двум причинам:

L>1. Теряешь оригинальный стек. Его, конечно, можно восстановить, но придется будить внутреннего мыщъх'а. Короче, удачной отладки крешдампа!
L>2. Размазываешь обработку ошибок почем зря

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

L>То есть весь процесс спрятан внутри корутины, и единственный случай, когда происходит выход из нее — когда соединение закрыто. При этом все ошибки, связанные собственно с тем, что творилось в этом соединении, обрабатываются локально и не выпускаются наружу.

L>Попытка выпустить исключение для обработки в вызываемом контексте ИМХО убивает все преимущества использования корути на корню и запутывает код.

У меня другой юзкейс. Работа с соединением происходит в асинхронной манере с помощью обычных колбеков, без всяких заморочек. IMO это лучше, если код не очень сложен. Корутины я использую для парсинга данных пришедших от сервера. Мой сервер умеет read ahead. Обычно сервер сначала должен прочитать из сокета заголовок сообщения фикс. размера, потом узнать размер тела сообщения и начать читать его. Получается две операции чтения на одно сообщения. Вместо этого мой сервер берет буфер и читает столько данных, сколько в буфер поместится, после того как данные получены, буфер содержит нецелое количество сообщений. Написать парсер данных, который будет без лишнего копирования парсить это дело и куда-нибудь отдавать довольно сложно. Тут приходят на помощь корутины. Я организовал все так, чтобы код сервера просто отдавал буфер парсеру, а код парсера просто выполнялся последовательно в корутине и читал данные из потока, как только буфер закончился, парсер делал yield и управление возвращалось серверу. Получается что данные не копируются и код парсера работает так, словно данные лежат в одном большом массиве, т.е. выглядит абсолютно линейным и простым. У меня такой сервер обрабатывает чуть больше двух миллионов сообщений в секунду на амазоновском сервере.

void ProtocolParser::worker(Caller& caller) {
    // Remember caller for use in ByteStreamReader's methods
    set_caller(caller);
    // Buffer to read strings from
    const int     buffer_len         = RESPStream::STRING_LENGTH_MAX;
    Byte          buffer[buffer_len] = {};
    int           bytes_read         = 0;
    // Data to read
    aku_ParamId   id                 = 0;
    std::string   sid;
    bool          integer_id         = false;
    aku_TimeStamp ts                 = 0;
    double        value              =.0;
    //
    try {
        RESPStream stream(this);
        while(true) {
            // read id
            auto next = stream.next_type();
            switch(next) {
            case RESPStream::INTEGER:
                id = stream.read_int();
                integer_id = true;
                break;
            case RESPStream::STRING:
                bytes_read = stream.read_string(buffer, buffer_len);
                sid = std::string(buffer, buffer + bytes_read);
                integer_id = false;
                break;
            case RESPStream::BULK_STR:
                // Compressed chunk of data
                bytes_read = stream.read_bulkstr(buffer, buffer_len);
                consumer_->add_bulk_string(buffer, bytes_read);
                continue;
            default:
                // Bad frame
                {
                    std::string msg;
                    size_t pos;
                    std::tie(msg, pos) = get_error_context("unexpected parameter id format");
                    BOOST_THROW_EXCEPTION(ProtocolParserError(msg, pos));
                }
            };
...


Тут все обращения к методам stream могут сделать yield и вернут управление серверу, а когда появится буфер с новыми данными — все продолжит исполняться с того же места, оч. удобно, не нужно городить сложную стейт машину для парсинга.

Собственно исключение там нужно для того, чтобы в случае ошибки отправить клиенту назад сообщение об ошибке, описывающее где именно его данные неверны, и затем закрыть сообщение. Парсер сделать это не может, значит он должен как-то передавать эту инф. на верхний уровент — TCP серверу. Таскать контекст при передаче каждого буфера и проверять его — накладно и сложно (усложняет код парсера), а вот исключения очень даже хорошо работают в этом случае.
Отредактировано 28.01.2015 13:10 chaotic-good . Предыдущая версия .
Re[5]: Проблемы с boost::coroutine
От: landerhigh Пират  
Дата: 28.01.15 14:32
Оценка:
Здравствуйте, chaotic-good, Вы писали:


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


Я не смотрел пока на линукс, но для получения дампа с нормальнм стеком при взрыве в корутине в Виндовс есть работающее решение — код корутины заворачивается в __try, а __except вызывает фильтр, который и занимается созданием дампа. Получается нормальный дамп с живым стеком корутины.

CG>У меня другой юзкейс. Работа с соединением происходит в асинхронной манере с помощью обычных колбеков, без всяких заморочек.


Такой же, на самом деле. Я использую асинхронные методы asio, которые просто из колбеков передают управление в корутину. Один-в-один то, что у тебя.

GC>Вместо этого мой сервер берет буфер и читает столько данных, сколько в буфер поместится, после того как данные получены, буфер содержит нецелое количество сообщений. Написать парсер данных, который будет без лишнего копирования парсить это дело и куда-нибудь отдавать довольно сложно. Тут приходят на помощь корутины.


+

CG>Собственно исключение там нужно для того, чтобы в случае ошибки отправить клиенту назад сообщение об ошибке, описывающее где именно его данные неверны, и затем закрыть сообщение. Парсер сделать это не может, значит он должен как-то передавать эту инф. на верхний уровент — TCP серверу. Таскать контекст при передаче каждого буфера и проверять его — накладно и сложно (усложняет код парсера), а вот исключения очень даже хорошо работают в этом случае.


Тебе тут вообще эксепшен нафиг не уперся. Ну совсем:

void myCoro(Caller& caller)
{
    // a lot of code here
    if (error)
    {
        caller.setError(ErrorMessage("Parsing error at position %d", pos));
        return;
    }
}



дальше элементарно. Но возникает вопрос, что делать, если stream.read_string() обламывается из-за потери соединения? ИМХО, примерно то же самое, а уж вызываемый контекст пусть сам решает, что ему делать — переподключаться, ждать и т.п.
www.blinnov.com
Re[6]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 14:43
Оценка:
L>Тебе тут вообще эксепшен нафиг не уперся. Ну совсем:

L>
L>void myCoro(Caller& caller)
L>{
L>    // a lot of code here
L>    if (error)
L>    {
L>        caller.setError(ErrorMessage("Parsing error at position %d", pos));
L>        return;
L>    }
L>}

L>


Можно и так сделать, да.


L>дальше элементарно. Но возникает вопрос, что делать, если stream.read_string() обламывается из-за потери соединения? ИМХО, примерно то же самое, а уж вызываемый контекст пусть сам решает, что ему делать — переподключаться, ждать и т.п.


Он не может потерять соединение, он просто буфер парсит и все. Потерять соединение может тот, кто вызывает корутину, вот он то уже и знает как обрабатывать потерю соединения. Все вполне логично.
Re[7]: Проблемы с boost::coroutine
От: landerhigh Пират  
Дата: 28.01.15 16:04
Оценка:
Здравствуйте, chaotic-good, Вы писали:


L>>дальше элементарно. Но возникает вопрос, что делать, если stream.read_string() обламывается из-за потери соединения? ИМХО, примерно то же самое, а уж вызываемый контекст пусть сам решает, что ему делать — переподключаться, ждать и т.п.


CG>Он не может потерять соединение, он просто буфер парсит и все. Потерять соединение может тот, кто вызывает корутину, вот он то уже и знает как обрабатывать потерю соединения. Все вполне логично.


А если вызывающий решин, что нужно начать сначала, как он корректно завершает корутину в таком случае? Просто интересно.

В моем случае только изначальное выполнялось снаружи корутины. Как только соединение появлялось, и для него появлялась работа, т.е. объект типа "TaskQueue" становился не очень пустым, соединение и очередь передавались в корутину, а дальше вся ответственность за работу с соединением была на самой корутине. Выход из корутины только в двух случаях — нечего делать и/или облом соединения, причем первый случай был сделан исключительно для того, чтобы была практическая возможность сэкономить на стеке и иметь меньше корутин, чем соединений.
www.blinnov.com
Re[8]: Проблемы с boost::coroutine
От: chaotic-good  
Дата: 28.01.15 17:32
Оценка:
CG>>Он не может потерять соединение, он просто буфер парсит и все. Потерять соединение может тот, кто вызывает корутину, вот он то уже и знает как обрабатывать потерю соединения. Все вполне логично.

L>А если вызывающий решин, что нужно начать сначала, как он корректно завершает корутину в таком случае? Просто интересно.


Он у меня не может начать сначала, при старте тисипи сессии мы создаем объект ProtocolParser — корутину и фигачим в нее пакеты с данными. Фигачиние может остановиться по инициативе извне (вызов метода close) или по инициативе изнутри (ошибка в переданных внутрь данных). Рестарта нет.

L>В моем случае только изначальное выполнялось снаружи корутины. Как только соединение появлялось, и для него появлялась работа, т.е. объект типа "TaskQueue" становился не очень пустым, соединение и очередь передавались в корутину, а дальше вся ответственность за работу с соединением была на самой корутине. Выход из корутины только в двух случаях — нечего делать и/или облом соединения, причем первый случай был сделан исключительно для того, чтобы была практическая возможность сэкономить на стеке и иметь меньше корутин, чем соединений.


У меня работа с сокетом происходит в обычном режиме, с помощью обычных колбэков, в корутину же передаются только буферы с данными, где они парсятся. Я решил всегда создавать новую крутину на соединение ибо соединения планируются долгоживущие. Посмотреть можно тут — *.h и *.cpp, там суть в том, что сервер дергает метод push_next, в котором буфер добавляется в очередь и делается yield в корутину. Когда данные зананчиваются, корутина делает yield обратно и сервер продолжает работать. Пока все это происходит, уже может прийти следующая порция данных и тут же вызовется следующий коллбек, который снова дернет push_next и так далее.
Re[9]: Проблемы с boost::coroutine
От: landerhigh Пират  
Дата: 28.01.15 20:00
Оценка:
Здравствуйте, chaotic-good, Вы писали:

L>>А если вызывающий решин, что нужно начать сначала, как он корректно завершает корутину в таком случае? Просто интересно.


CG>Он у меня не может начать сначала, при старте тисипи сессии мы создаем объект ProtocolParser — корутину и фигачим в нее пакеты с данными. Фигачиние может остановиться по инициативе извне (вызов метода close) или по инициативе изнутри (ошибка в переданных внутрь данных). Рестарта нет.


У меня вопрос скорее в том, чтобы корректно завершить корутину, т.е. дать ей шанс размотать стек. А то был у нас прецендент...
Впрочем, вижу, что при закрытии стрима в случае ожидания на get() будет выброшено исключение.

CG>У меня работа с сокетом происходит в обычном режиме, с помощью обычных колбэков, в корутину же передаются только буферы с данными, где они парсятся. Я решил всегда создавать новую крутину на соединение ибо соединения планируются долгоживущие. Посмотреть можно тут — *.h и *.cpp, там суть в том, что сервер дергает метод push_next, в котором буфер добавляется в очередь и делается yield в корутину. Когда данные зананчиваются, корутина делает yield обратно и сервер продолжает работать. Пока все это происходит, уже может прийти следующая порция данных и тут же вызовется следующий коллбек, который снова дернет push_next и так далее.


А, ну это стандартный подход, на самом деле. Реализации бывают разные только.
www.blinnov.com
Re[9]: Проблемы с boost::coroutine
От: nen777w  
Дата: 30.01.15 23:50
Оценка:
CG>У меня работа с сокетом происходит в обычном режиме, с помощью обычных колбэков, в корутину же передаются только буферы с данными, где они парсятся. Я решил всегда создавать новую крутину на соединение ибо соединения планируются долгоживущие. Посмотреть можно тут — *.h и *.cpp, там суть в том, что сервер дергает метод push_next, в котором буфер добавляется в очередь и делается yield в корутину. Когда данные зананчиваются, корутина делает yield обратно и сервер продолжает работать. Пока все это происходит, уже может прийти следующая порция данных и тут же вызовется следующий коллбек, который снова дернет push_next и так далее.

Прошу прощения что влезаю в дискуссию. Т.к. сам недавно начал изучать корутины и их применение, тема стала интересна.
Но это офтопик, просто интересуюсь почему сделали так:
case RESPStream::STRING:
                bytes_read = stream.read_string(buffer, buffer_len);
                value = strtod(buffer, nullptr);
                memset(buffer, 0, bytes_read);

зачем тут нужен memset() ?
Насколько я понимаю stream.read_string() (который RESPStream) читает строку из потока до '\0' а значит наверно проще будет дополнять buffer[bytes_read+1] = '\0'
А что бы гарантировать что мы не вылезем за пределы buffer можно алоцировать его на байт больше инициализировав последний '\0' значением, что наверно проще чем занулять буфер.
Хотя тут же в коде нет проверки на то что что bytes_read != 0 а в резултатет можно получить в value ложный 0.

спасибо за живой код, самому уже хочется пописать что-то с корутинами.
Re[4]: Проблемы с boost::coroutine
От: __Nicolay Россия  
Дата: 10.02.15 09:36
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, chaotic-good, Вы писали:


A>>>SSCCE или GTFO.


CG>>это невозможно по ряду причин, воспроизводится не везде, требует сложной сборки двух бинарников, в общем, я к опыту взываю, может кто просто сталкивался с подобным уже


J>пальцем в небо — исключение пересекает границу so? У меня такая радость с gcc безо всяких корутин — исключение из so в главной проге не всегда ловится (с gcc3 проблем не было, началось с gcc4).


О! У нас та же проблема. Как боретесь?
Re[5]: Проблемы с boost::coroutine
От: jazzer Россия Skype: enerjazzer
Дата: 10.02.15 09:44
Оценка:
Здравствуйте, __Nicolay, Вы писали:

J>>пальцем в небо — исключение пересекает границу so? У меня такая радость с gcc безо всяких корутин — исключение из so в главной проге не всегда ловится (с gcc3 проблем не было, началось с gcc4).


__N>О! У нас та же проблема. Как боретесь?


Да никак. Запускаем еще раз под gdb и смотрим, где отвалилось. Все равно это редко и случается обычно только на этапе инициализации, когда конфиг кривой или файл не нашелся или еще чего-нибудь... в остальных случаях все летает внутри DLL и успешно ловится.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.